mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
Release calc version 2.10.3t5.45
This commit is contained in:
14
BUGS
14
BUGS
@@ -10,7 +10,8 @@ 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:
|
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 it does not, then something is really broken!
|
||||||
|
|
||||||
@@ -79,16 +80,11 @@ of a context diff patch) to:
|
|||||||
|
|
||||||
Known problems or mis-features:
|
Known problems or mis-features:
|
||||||
|
|
||||||
* In calc2.10.2t3, when scan() reads characters from stdin, they
|
* Many of and SEE ALSO sections of help files
|
||||||
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.
|
|
||||||
|
|
||||||
* Many of LIBRARY, LIMITS and SEE ALSO sections of help files
|
|
||||||
for builtins are either inconsistent or missing information.
|
for builtins are either inconsistent or missing information.
|
||||||
|
|
||||||
* The functions filepos2z() and z2filepos() do not work (or
|
* Many of the LIBRARY sections are incorrect now that libcalc.a
|
||||||
worse do not compile) when FILEPOS is 64 bits long.
|
contains most of the calc system.
|
||||||
|
|
||||||
* There is some places in the source with obscure variable names
|
* 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 not much in the way of comments. We need some major cleanup
|
||||||
|
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
|
There are also many numeric functions such as factorial and gcd, along
|
||||||
with some transcendental functions such as sin and exp.
|
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
|
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
|
The function libcalc_call_me_first() takes no args and returns void. You
|
||||||
need call libcalc_call_me_first() only once.
|
need call libcalc_call_me_first() only once.
|
||||||
@@ -98,7 +104,11 @@ For example:
|
|||||||
...
|
...
|
||||||
|
|
||||||
if ((error = setjmp(calc_jmp_buf)) != 0) {
|
if ((error = setjmp(calc_jmp_buf)) != 0) {
|
||||||
/* handle error */
|
|
||||||
|
/* reinitialize calc after a longjmp */
|
||||||
|
reinitialize();
|
||||||
|
|
||||||
|
/* report the error */
|
||||||
printf("Ouch: %s\n", calc_error);
|
printf("Ouch: %s\n", calc_error);
|
||||||
}
|
}
|
||||||
calc_jmp = 1;
|
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
|
There are three predefined values for complex numbers. You should clink
|
||||||
them when you want to use them. They are _czero_, _cone_, and _conei_.
|
them when you want to use them. They are _czero_, _cone_, and _conei_.
|
||||||
These have the values 0, 1, and i.
|
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.
|
||||||
|
4
README
4
README
@@ -1,10 +1,10 @@
|
|||||||
# Copyright (c) 1994 David I. Bell
|
# Copyright (c) 1997 David I. Bell
|
||||||
# Permission is granted to use, distribute, or modify this source,
|
# Permission is granted to use, distribute, or modify this source,
|
||||||
# provided that this copyright notice remains intact.
|
# provided that this copyright notice remains intact.
|
||||||
#
|
#
|
||||||
# Arbitrary precision calculator.
|
# Arbitrary precision calculator.
|
||||||
|
|
||||||
I am allowing this calculator to be freely distributed for personal uses.
|
I am allowing this calculator to be freely distributed for your enjoyment.
|
||||||
Like all multi-precision programs, you should not depend absolutely on
|
Like all multi-precision programs, you should not depend absolutely on
|
||||||
its results, since bugs in such programs can be insidious and only rarely
|
its results, since bugs in such programs can be insidious and only rarely
|
||||||
show up.
|
show up.
|
||||||
|
358
addop.c
358
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,
|
* Permission is granted to use, distribute, or modify this source,
|
||||||
* provided that this copyright notice remains intact.
|
* provided that this copyright notice remains intact.
|
||||||
*
|
*
|
||||||
* Add opcodes to a function being compiled.
|
* Add opcodes to a function being compiled.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "calc.h"
|
#include "calc.h"
|
||||||
#include "opcodes.h"
|
#include "opcodes.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
@@ -22,6 +23,7 @@
|
|||||||
static long maxopcodes; /* number of opcodes available */
|
static long maxopcodes; /* number of opcodes available */
|
||||||
static long newindex; /* index of new function */
|
static long newindex; /* index of new function */
|
||||||
static long oldop; /* previous opcode */
|
static long oldop; /* previous opcode */
|
||||||
|
static long oldoldop; /* opcode before previous opcode */
|
||||||
static long debugline; /* line number of latest debug opcode */
|
static long debugline; /* line number of latest debug opcode */
|
||||||
static long funccount; /* number of functions */
|
static long funccount; /* number of functions */
|
||||||
static long funcavail; /* available number of functions */
|
static long funcavail; /* available number of functions */
|
||||||
@@ -61,20 +63,25 @@ showfunctions(void)
|
|||||||
{
|
{
|
||||||
FUNC **fpp; /* pointer into function table */
|
FUNC **fpp; /* pointer into function table */
|
||||||
FUNC *fp; /* current function */
|
FUNC *fp; /* current function */
|
||||||
|
long count;
|
||||||
|
|
||||||
if (funccount == 0) {
|
count = 0;
|
||||||
printf("No user functions defined.\n");
|
if (funccount > 0) {
|
||||||
return;
|
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");
|
if (count > 0) {
|
||||||
printf("---- ---------\n");
|
printf("\nNumber: %ld\n", count);
|
||||||
for (fpp = &functions[funccount - 1]; fpp >= functions; fpp--) {
|
} else {
|
||||||
fp = *fpp;
|
printf("No user functions defined\n");
|
||||||
if (fp == NULL)
|
|
||||||
continue;
|
|
||||||
printf("%-12s %-2d\n", fp->f_name, fp->f_paramcount);
|
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -112,6 +119,7 @@ beginfunc(char *name, BOOL newflag)
|
|||||||
initlocals();
|
initlocals();
|
||||||
initlabels();
|
initlabels();
|
||||||
oldop = OP_NOP;
|
oldop = OP_NOP;
|
||||||
|
oldoldop = OP_NOP;
|
||||||
debugline = 0;
|
debugline = 0;
|
||||||
errorcount = 0;
|
errorcount = 0;
|
||||||
}
|
}
|
||||||
@@ -128,8 +136,13 @@ endfunc(void)
|
|||||||
register FUNC *fp; /* function just finished */
|
register FUNC *fp; /* function just finished */
|
||||||
unsigned long size; /* size of just created function */
|
unsigned long size; /* size of just created function */
|
||||||
|
|
||||||
|
if (oldop != OP_RETURN) {
|
||||||
|
addop(OP_UNDEF);
|
||||||
|
addop(OP_RETURN);
|
||||||
|
}
|
||||||
checklabels();
|
checklabels();
|
||||||
if (errorcount) {
|
if (errorcount) {
|
||||||
|
freefunc(curfunc);
|
||||||
printf("\"%s\": %ld error%s\n", curfunc->f_name, errorcount,
|
printf("\"%s\": %ld error%s\n", curfunc->f_name, errorcount,
|
||||||
((errorcount == 1) ? "" : "s"));
|
((errorcount == 1) ? "" : "s"));
|
||||||
return;
|
return;
|
||||||
@@ -151,13 +164,15 @@ endfunc(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (functions[newindex]) {
|
if (functions[newindex]) {
|
||||||
|
freenumbers(functions[newindex]);
|
||||||
free(functions[newindex]);
|
free(functions[newindex]);
|
||||||
fprintf(stderr, "**** %s() has been redefined\n", fp->f_name);
|
if (inputisterminal() || conf->lib_debug >= 0)
|
||||||
|
printf("%s() redefined\n", fp->f_name);
|
||||||
}
|
}
|
||||||
|
else if (inputisterminal() || conf->lib_debug >= 0)
|
||||||
|
printf("%s() defined\n", fp->f_name);
|
||||||
functions[newindex] = fp;
|
functions[newindex] = fp;
|
||||||
objuncache();
|
objuncache();
|
||||||
if (inputisterminal())
|
|
||||||
printf("\"%s\" defined\n", fp->f_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -195,6 +210,83 @@ adduserfunc(char *name)
|
|||||||
return index;
|
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 >= 0)
|
||||||
|
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.
|
* Clear any optimization that may be done for the next opcode.
|
||||||
@@ -204,6 +296,7 @@ void
|
|||||||
clearopt(void)
|
clearopt(void)
|
||||||
{
|
{
|
||||||
oldop = OP_NOP;
|
oldop = OP_NOP;
|
||||||
|
oldoldop = OP_NOP;
|
||||||
debugline = 0;
|
debugline = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,10 +346,17 @@ void
|
|||||||
addop(long op)
|
addop(long op)
|
||||||
{
|
{
|
||||||
register FUNC *fp; /* current function */
|
register FUNC *fp; /* current function */
|
||||||
NUMBER *q;
|
NUMBER *q, *q1, *q2;
|
||||||
|
unsigned long count;
|
||||||
|
BOOL cut;
|
||||||
|
int diff;
|
||||||
|
|
||||||
fp = curfunc;
|
fp = curfunc;
|
||||||
if ((fp->f_opcodecount + 5) >= maxopcodes) {
|
count = fp->f_opcodecount;
|
||||||
|
cut = TRUE;
|
||||||
|
diff = 2;
|
||||||
|
q = NULL;
|
||||||
|
if ((count + 5) >= maxopcodes) {
|
||||||
maxopcodes += OPCODEALLOCSIZE;
|
maxopcodes += OPCODEALLOCSIZE;
|
||||||
fp = (FUNC *) malloc(funcsize(maxopcodes));
|
fp = (FUNC *) malloc(funcsize(maxopcodes));
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
@@ -269,73 +369,169 @@ addop(long op)
|
|||||||
free(curfunc);
|
free(curfunc);
|
||||||
curfunc = fp;
|
curfunc = fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the current opcode against the previous opcode and try to
|
* Check the current opcode against the previous opcode and try to
|
||||||
* slightly optimize the code depending on the various combinations.
|
* slightly optimize the code depending on the various combinations.
|
||||||
*/
|
*/
|
||||||
if (op == OP_GETVALUE) {
|
switch (op) {
|
||||||
switch (oldop) {
|
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:
|
if (cut) {
|
||||||
case OP_UNDEF: case OP_GETCONFIG: case OP_SETCONFIG:
|
fp->f_opcodes[count - diff] = oldop;
|
||||||
return;
|
return;
|
||||||
case OP_DUPLICATE:
|
}
|
||||||
fp->f_opcodes[fp->f_opcodecount - 1] = OP_DUPVALUE;
|
break;
|
||||||
oldop = OP_DUPVALUE;
|
case OP_POP:
|
||||||
return;
|
switch (oldop) {
|
||||||
case OP_FIADDR:
|
case OP_ASSIGN:
|
||||||
fp->f_opcodes[fp->f_opcodecount - 1] = OP_FIVALUE;
|
fp->f_opcodes[count-1] = OP_ASSIGNPOP;
|
||||||
oldop = OP_FIVALUE;
|
oldop = OP_ASSIGNPOP;
|
||||||
return;
|
return;
|
||||||
case OP_GLOBALADDR:
|
case OP_NUMBER:
|
||||||
fp->f_opcodes[fp->f_opcodecount - 2] = OP_GLOBALVALUE;
|
case OP_IMAGINARY:
|
||||||
oldop = OP_GLOBALVALUE;
|
q = constvalue(fp->f_opcodes[count-1]);
|
||||||
return;
|
qfree(q);
|
||||||
case OP_LOCALADDR:
|
break;
|
||||||
fp->f_opcodes[fp->f_opcodecount - 2] = OP_LOCALVALUE;
|
case OP_STRING:
|
||||||
oldop = OP_LOCALVALUE;
|
sfree(findstring((long)fp->f_opcodes[count-1]));
|
||||||
return;
|
break;
|
||||||
case OP_PARAMADDR:
|
case OP_LOCALADDR:
|
||||||
fp->f_opcodes[fp->f_opcodecount - 2] = OP_PARAMVALUE;
|
case OP_PARAMADDR:
|
||||||
oldop = OP_PARAMVALUE;
|
break;
|
||||||
return;
|
case OP_GLOBALADDR:
|
||||||
case OP_ELEMADDR:
|
diff = 1 + PTR_SIZE;
|
||||||
fp->f_opcodes[fp->f_opcodecount - 2] = OP_ELEMVALUE;
|
break;
|
||||||
oldop = OP_ELEMVALUE;
|
default:
|
||||||
return;
|
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)) {
|
if (oldop == OP_NUMBER) {
|
||||||
q = constvalue(fp->f_opcodes[fp->f_opcodecount - 1]);
|
if (oldoldop == OP_NUMBER) {
|
||||||
fp->f_opcodes[fp->f_opcodecount - 1] = addqconstant(qneg(q));
|
q1 = constvalue(fp->f_opcodes[count - 3]);
|
||||||
oldop = OP_NUMBER;
|
q2 = constvalue(fp->f_opcodes[count - 1]);
|
||||||
return;
|
switch (op) {
|
||||||
}
|
case OP_DIV:
|
||||||
if ((op == OP_POWER) && (oldop == OP_NUMBER)) {
|
if (qiszero(q2)) {
|
||||||
if (qcmpi(constvalue(fp->f_opcodes[fp->f_opcodecount - 1]), 2L) == 0) {
|
cut = FALSE;
|
||||||
fp->f_opcodecount--;
|
break;
|
||||||
fp->f_opcodes[fp->f_opcodecount - 1] = OP_SQUARE;
|
}
|
||||||
oldop = OP_SQUARE;
|
q = qqdiv(q1,q2);
|
||||||
return;
|
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.
|
* No optimization possible, so store the opcode.
|
||||||
*/
|
*/
|
||||||
fp->f_opcodes[fp->f_opcodecount] = op;
|
fp->f_opcodes[fp->f_opcodecount] = op;
|
||||||
fp->f_opcodecount++;
|
fp->f_opcodecount++;
|
||||||
|
oldoldop = oldop;
|
||||||
oldop = op;
|
oldop = op;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,24 +543,7 @@ addop(long op)
|
|||||||
void
|
void
|
||||||
addopone(long op, long arg)
|
addopone(long op, long arg)
|
||||||
{
|
{
|
||||||
NUMBER *q;
|
if (op == OP_DEBUG) {
|
||||||
|
|
||||||
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 ((conf->traceflags & TRACE_NODEBUG) || (arg == debugline))
|
if ((conf->traceflags & TRACE_NODEBUG) || (arg == debugline))
|
||||||
return;
|
return;
|
||||||
debugline = arg;
|
debugline = arg;
|
||||||
@@ -372,7 +551,6 @@ addopone(long op, long arg)
|
|||||||
curfunc->f_opcodes[curfunc->f_opcodecount - 1] = arg;
|
curfunc->f_opcodes[curfunc->f_opcodecount - 1] = arg;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
addop(op);
|
addop(op);
|
||||||
curfunc->f_opcodes[curfunc->f_opcodecount] = arg;
|
curfunc->f_opcodes[curfunc->f_opcodecount] = arg;
|
||||||
|
22
alloc.h
22
alloc.h
@@ -1,16 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1995 David I. Bell
|
* Copyright (c) 1997 David I. Bell
|
||||||
* Permission is granted to use, distribute, or modify this source,
|
* Permission is granted to use, distribute, or modify this source,
|
||||||
* provided that this copyright notice remains intact.
|
* provided that this copyright notice remains intact.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if !defined(ALLOC_H)
|
#if !defined(__ALLOC_H__)
|
||||||
#define ALLOC_H
|
#define __ALLOC_H__
|
||||||
|
|
||||||
|
|
||||||
#include "have_malloc.h"
|
#include "have_malloc.h"
|
||||||
#include "have_newstr.h"
|
#include "have_newstr.h"
|
||||||
#include "have_string.h"
|
#include "have_string.h"
|
||||||
|
#include "have_memmv.h"
|
||||||
|
|
||||||
#ifdef HAVE_MALLOC_H
|
#ifdef HAVE_MALLOC_H
|
||||||
# include <malloc.h>
|
# include <malloc.h>
|
||||||
@@ -37,7 +39,7 @@ extern void *memset();
|
|||||||
# if defined(__STDC__) && __STDC__ != 0
|
# if defined(__STDC__) && __STDC__ != 0
|
||||||
extern size_t strlen();
|
extern size_t strlen();
|
||||||
# else
|
# else
|
||||||
extern long strlen(); /* should be size_t, but old systems don't have it */
|
extern long strlen();
|
||||||
# endif
|
# endif
|
||||||
# else /* HAVE_NEWSTR */
|
# else /* HAVE_NEWSTR */
|
||||||
extern void bcopy();
|
extern void bcopy();
|
||||||
@@ -61,4 +63,14 @@ extern int strcmp();
|
|||||||
#define strchr(s, c) index(s, c)
|
#define strchr(s, c) index(s, c)
|
||||||
#endif /* HAVE_NEWSTR */
|
#endif /* HAVE_NEWSTR */
|
||||||
|
|
||||||
#endif /* !ALLOC_H */
|
#if !defined(HAVE_MEMMOVE)
|
||||||
|
# undef CALC_SIZE_T
|
||||||
|
# if defined(__STDC__) && __STDC__ != 0
|
||||||
|
# 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_dim = dim;
|
||||||
ep->e_hash = hash;
|
ep->e_hash = hash;
|
||||||
ep->e_value.v_type = V_NULL;
|
ep->e_value.v_type = V_NULL;
|
||||||
|
ep->e_value.v_subtype = V_NOSUBTYPE;
|
||||||
for (i = 0; i < dim; i++)
|
for (i = 0; i < dim; i++)
|
||||||
copyvalue(&indices[i], &ep->e_indices[i]);
|
copyvalue(&indices[i], &ep->e_indices[i]);
|
||||||
ep->e_next = *listhead;
|
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
|
* Search an association for the specified value starting at the
|
||||||
* specified index. Returns the element number (zero based) of the
|
* specified index. Returns 0 and stores index if value found,
|
||||||
* found value, or -1 if the value was not found.
|
* otherwise returns 1.
|
||||||
*/
|
*/
|
||||||
long
|
int
|
||||||
assocsearch(ASSOC *ap, VALUE *vp, long index)
|
assocsearch(ASSOC *ap, VALUE *vp, long i, long j, ZVALUE *index)
|
||||||
{
|
{
|
||||||
ASSOCELEM *ep;
|
ASSOCELEM *ep;
|
||||||
|
|
||||||
if (index < 0)
|
if (i < 0 || j > ap->a_count) {
|
||||||
index = 0;
|
math_error("This should not happen in assocsearch");
|
||||||
while (TRUE) {
|
/*NOTREACHED*/
|
||||||
ep = elemindex(ap, index);
|
|
||||||
if (ep == NULL)
|
|
||||||
return -1;
|
|
||||||
if (!comparevalue(&ep->e_value, vp))
|
|
||||||
return index;
|
|
||||||
index++;
|
|
||||||
}
|
}
|
||||||
|
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
|
* Search an association backwards for the specified value starting at the
|
||||||
* specified index. Returns the element number (zero based) of the
|
* specified index. Returns 0 and stores the index if the value is
|
||||||
* found value, or -1 if the value was not found.
|
* found; otherwise returns 1.
|
||||||
*/
|
*/
|
||||||
long
|
int
|
||||||
assocrsearch(ASSOC *ap, VALUE *vp, long index)
|
assocrsearch(ASSOC *ap, VALUE *vp, long i, long j, ZVALUE *index)
|
||||||
{
|
{
|
||||||
ASSOCELEM *ep;
|
ASSOCELEM *ep;
|
||||||
|
|
||||||
if (index >= ap->a_count)
|
if (i < 0 || j > ap->a_count) {
|
||||||
index = ap->a_count - 1;
|
math_error("This should not happen in assocsearch");
|
||||||
while (TRUE) {
|
/*NOTREACHED*/
|
||||||
ep = elemindex(ap, index);
|
|
||||||
if (ep == NULL)
|
|
||||||
return -1;
|
|
||||||
if (!comparevalue(&ep->e_value, vp))
|
|
||||||
return index;
|
|
||||||
index--;
|
|
||||||
}
|
}
|
||||||
|
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__ */
|
755
block.c
Normal file
755
block.c
Normal file
@@ -0,0 +1,755 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* chongo@toad.com
|
||||||
|
* ...!{pyramid,sun,uunet}!hoptoad!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 *new; /* new block allocated */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* firewall
|
||||||
|
*/
|
||||||
|
if (len < 0)
|
||||||
|
len = 0;
|
||||||
|
if (chunk <= 0)
|
||||||
|
chunk = BLK_CHUNKSIZE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* allocate BLOCK
|
||||||
|
*/
|
||||||
|
new = (BLOCK *)malloc(sizeof(BLOCK));
|
||||||
|
if (new == NULL) {
|
||||||
|
math_error("cannot allocate block");
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initialize BLOCK
|
||||||
|
*/
|
||||||
|
new->blkchunk = chunk;
|
||||||
|
new->maxsize = ((len+chunk)/chunk)*chunk;
|
||||||
|
new->data = (USB8*)malloc(new->maxsize);
|
||||||
|
if (new->data == NULL) {
|
||||||
|
math_error("cannot allocate block data storage");
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
memset(new->data, 0, new->maxsize);
|
||||||
|
new->datalen = len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return BLOCK
|
||||||
|
*/
|
||||||
|
if (conf->calc_debug > 0) {
|
||||||
|
blkchk(new);
|
||||||
|
}
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 *new; /* 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 */
|
||||||
|
new = (USB8*)realloc(blk->data, newmax);
|
||||||
|
if (new == NULL) {
|
||||||
|
math_error("cannot reallocate block storage");
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear any new storage */
|
||||||
|
if (newmax > blk->maxsize) {
|
||||||
|
memset(new + blk->maxsize, 0, (newmax - blk->maxsize));
|
||||||
|
}
|
||||||
|
blk->maxsize = newmax;
|
||||||
|
|
||||||
|
/* restore the data pointers */
|
||||||
|
blk->data = new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 *new; /* copy of blk */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* malloc new block
|
||||||
|
*/
|
||||||
|
new = (BLOCK *)malloc(sizeof(BLOCK));
|
||||||
|
if (new == NULL) {
|
||||||
|
math_error("blk_copy: cannot malloc BLOCK");
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* duplicate most of the block
|
||||||
|
*/
|
||||||
|
*new = *blk;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* duplicate block data
|
||||||
|
*/
|
||||||
|
new->data = (USB8 *)malloc(blk->maxsize);
|
||||||
|
if (new->data == NULL) {
|
||||||
|
math_error("blk_copy: cannot duplicate block data");
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
memcpy(new->data, blk->data, blk->maxsize);
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
230
block.h
Normal file
230
block.h
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* chongo@toad.com
|
||||||
|
* ...!{pyramid,sun,uunet}!hoptoad!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 *
|
HALF *
|
||||||
swap_b8_in_HALFs(HALF *dest, HALF *src, LEN len)
|
swap_b8_in_HALFs(HALF *dest, HALF *src, LEN len)
|
||||||
{
|
{
|
||||||
|
HALF *ret;
|
||||||
LEN i;
|
LEN i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -47,6 +48,7 @@ swap_b8_in_HALFs(HALF *dest, HALF *src, LEN len)
|
|||||||
if (dest == NULL) {
|
if (dest == NULL) {
|
||||||
dest = alloc(len);
|
dest = alloc(len);
|
||||||
}
|
}
|
||||||
|
ret = dest;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* swap the array
|
* swap the array
|
||||||
@@ -58,7 +60,7 @@ swap_b8_in_HALFs(HALF *dest, HALF *src, LEN len)
|
|||||||
/*
|
/*
|
||||||
* return the result
|
* return the result
|
||||||
*/
|
*/
|
||||||
return dest;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -272,6 +274,7 @@ swap_b8_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all)
|
|||||||
HALF *
|
HALF *
|
||||||
swap_b16_in_HALFs(HALF *dest, HALF *src, LEN len)
|
swap_b16_in_HALFs(HALF *dest, HALF *src, LEN len)
|
||||||
{
|
{
|
||||||
|
HALF *ret;
|
||||||
LEN i;
|
LEN i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -280,6 +283,7 @@ swap_b16_in_HALFs(HALF *dest, HALF *src, LEN len)
|
|||||||
if (dest == NULL) {
|
if (dest == NULL) {
|
||||||
dest = alloc(len);
|
dest = alloc(len);
|
||||||
}
|
}
|
||||||
|
ret = dest;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* swap the array
|
* swap the array
|
||||||
@@ -291,7 +295,7 @@ swap_b16_in_HALFs(HALF *dest, HALF *src, LEN len)
|
|||||||
/*
|
/*
|
||||||
* return the result
|
* 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
|
* Permission to use, copy, modify, and distribute this software and
|
||||||
* its documentation for any purpose and without fee is hereby granted,
|
* its documentation for any purpose and without fee is hereby granted,
|
||||||
@@ -20,8 +20,10 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(BYTESWAP_H)
|
|
||||||
#define BYTESWAP_H
|
#if !defined(__BYTESWAP_H__)
|
||||||
|
#define __BYTESWAP_H__
|
||||||
|
|
||||||
|
|
||||||
#include "longbits.h"
|
#include "longbits.h"
|
||||||
|
|
||||||
@@ -163,4 +165,5 @@
|
|||||||
|
|
||||||
#endif /* LONG_BITS == 64 */
|
#endif /* LONG_BITS == 64 */
|
||||||
|
|
||||||
#endif /* !BYTESWAP_H */
|
|
||||||
|
#endif /* !__BYTESWAP_H__ */
|
||||||
|
344
calc.c
344
calc.c
@@ -1,14 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1995 David I. Bell
|
* Copyright (c) 1997 David I. Bell
|
||||||
* Permission is granted to use, distribute, or modify this source,
|
* Permission is granted to use, distribute, or modify this source,
|
||||||
* provided that this copyright notice remains intact.
|
* provided that this copyright notice remains intact.
|
||||||
*
|
*
|
||||||
* Arbitrary precision calculator.
|
* Arbitrary precision calculator.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
#define CALC_C
|
#define CALC_C
|
||||||
#include "calc.h"
|
#include "calc.h"
|
||||||
@@ -19,6 +22,10 @@
|
|||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "have_uid_t.h"
|
#include "have_uid_t.h"
|
||||||
|
#include "have_const.h"
|
||||||
|
#include "custom.h"
|
||||||
|
#include "math_error.h"
|
||||||
|
#include "args.h"
|
||||||
|
|
||||||
#include "have_unistd.h"
|
#include "have_unistd.h"
|
||||||
#if defined(HAVE_UNISTD_H)
|
#if defined(HAVE_UNISTD_H)
|
||||||
@@ -30,69 +37,32 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* in case we do not have certain .h files
|
|
||||||
*/
|
|
||||||
#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
|
* external and static definitions
|
||||||
*/
|
*/
|
||||||
int abortlevel; /* current level of aborts */
|
extern int abortlevel; /* current level of aborts */
|
||||||
BOOL inputwait; /* TRUE if in a terminal input wait */
|
extern BOOL inputwait; /* TRUE if in a terminal input wait */
|
||||||
jmp_buf jmpbuf; /* for errors */
|
extern 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 */
|
extern int isatty(int tty); /* TRUE if fd is a tty */
|
||||||
|
|
||||||
static int p_flag = FALSE; /* TRUE => pipe mode */
|
extern int p_flag; /* TRUE => pipe mode */
|
||||||
static int q_flag = FALSE; /* TRUE => don't execute rc files */
|
extern int q_flag; /* TRUE => don't execute rc files */
|
||||||
static int u_flag = FALSE; /* TRUE => unbuffer stdin and stdout */
|
extern int u_flag; /* TRUE => unbuffer stdin and stdout */
|
||||||
|
|
||||||
|
extern char *pager; /* $PAGER or default */
|
||||||
|
extern int stdin_tty; /* TRUE if stdin is a tty */
|
||||||
|
extern char *program; /* our name */
|
||||||
|
extern char cmdbuf[]; /* command line expression */
|
||||||
|
|
||||||
|
extern char *version(void); /* return version string */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* global permissions
|
* forward static functions
|
||||||
*/
|
*/
|
||||||
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 void intint(int arg); /* interrupt routine */
|
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.
|
* Top level calculator routine.
|
||||||
@@ -108,13 +78,34 @@ main(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* parse args
|
* parse args
|
||||||
*/
|
*/
|
||||||
|
program = argv[0];
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
while ((argc > 0) && (**argv == '-')) {
|
while ((argc > 0) && (**argv == '-')) {
|
||||||
for (str = &argv[0][1]; *str; str++) switch (*str) {
|
for (str = &argv[0][1]; *str; str++) switch (*str) {
|
||||||
|
case 'C':
|
||||||
|
#if defined(CUSTOM)
|
||||||
|
allow_custom = TRUE;
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
fprintf(stderr,
|
||||||
|
"Calc was built with custom functions "
|
||||||
|
"disabled, -C usage is disallowed\n");
|
||||||
|
/*
|
||||||
|
* we are too early in processing to call
|
||||||
|
* libcalc_call_me_last() - nothing to cleanup
|
||||||
|
*/
|
||||||
|
exit(1);
|
||||||
|
#endif /* CUSTOM */
|
||||||
|
case 'e':
|
||||||
|
no_env = TRUE;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
want_defhelp = 1;
|
want_defhelp = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'i':
|
||||||
|
ign_errmax = TRUE;
|
||||||
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
if (argv[0][2]) {
|
if (argv[0][2]) {
|
||||||
p = &argv[0][2];
|
p = &argv[0][2];
|
||||||
@@ -124,16 +115,29 @@ main(int argc, char **argv)
|
|||||||
argv++;
|
argv++;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "-m requires an arg\n");
|
fprintf(stderr, "-m requires an arg\n");
|
||||||
|
/*
|
||||||
|
* we are too early in processing to
|
||||||
|
* call libcalc_call_me_last()
|
||||||
|
* nothing to cleanup
|
||||||
|
*/
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (p[1] != '\0' || *p < '0' || *p > '7') {
|
if (p[1] != '\0' || *p < '0' || *p > '7') {
|
||||||
fprintf(stderr, "unknown -m arg\n");
|
fprintf(stderr, "unknown -m arg\n");
|
||||||
|
/*
|
||||||
|
* we are too early in processing to
|
||||||
|
* call libcalc_call_me_last()
|
||||||
|
* nothing to cleanup
|
||||||
|
*/
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
allow_read = (((*p-'0') & 04) > 0);
|
allow_read = (((*p-'0') & 04) > 0);
|
||||||
allow_write = (((*p-'0') & 02) > 0);
|
allow_write = (((*p-'0') & 02) > 0);
|
||||||
allow_exec = (((*p-'0') & 01) > 0);
|
allow_exec = (((*p-'0') & 01) > 0);
|
||||||
break;
|
break;
|
||||||
|
case 'n':
|
||||||
|
new_std = TRUE;
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
p_flag = TRUE;
|
p_flag = TRUE;
|
||||||
break;
|
break;
|
||||||
@@ -144,21 +148,37 @@ main(int argc, char **argv)
|
|||||||
u_flag = TRUE;
|
u_flag = TRUE;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
version(stdout);
|
printf("%s (version %s)\n",
|
||||||
|
CALC_TITLE, version());
|
||||||
|
/*
|
||||||
|
* we are too early in processing to call
|
||||||
|
* libcalc_call_me_last() - nothing to cleanup
|
||||||
|
*/
|
||||||
exit(0);
|
exit(0);
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unknown option\n");
|
fprintf(stderr,
|
||||||
|
"usage: %s [-C] [-e] [-h] [-i] [-m mode] [-n] [-p]\n",
|
||||||
|
program);
|
||||||
|
fprintf(stderr, "\t[-q] [-u] [calc_cmd ...]\n");
|
||||||
|
/*
|
||||||
|
* we are too early in processing to call
|
||||||
|
* libcalc_call_me_last() - nothing to cleanup
|
||||||
|
*/
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
cmdbuf[0] = '\0';
|
||||||
str = cmdbuf;
|
str = cmdbuf;
|
||||||
*str = '\0';
|
|
||||||
while (--argc >= 0) {
|
while (--argc >= 0) {
|
||||||
i = (long)strlen(*argv);
|
i = (long)strlen(*argv);
|
||||||
if (str+1+i+2 >= cmdbuf+MAXCMD) {
|
if (i+3 >= MAXCMD) {
|
||||||
fprintf(stderr, "command in arg list too long\n");
|
fprintf(stderr, "command in arg list too long\n");
|
||||||
|
/*
|
||||||
|
* we are too early in processing to call
|
||||||
|
* libcalc_call_me_last() - nothing to cleanup
|
||||||
|
*/
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
*str++ = ' ';
|
*str++ = ' ';
|
||||||
@@ -181,12 +201,11 @@ main(int argc, char **argv)
|
|||||||
* initialize
|
* initialize
|
||||||
*/
|
*/
|
||||||
libcalc_call_me_first();
|
libcalc_call_me_first();
|
||||||
hash_init();
|
stdin_tty = TRUE; /* assume internactive default */
|
||||||
file_init();
|
conf->tab_ok = TRUE; /* assume internactive default */
|
||||||
initenv();
|
|
||||||
resetinput();
|
|
||||||
if (want_defhelp) {
|
if (want_defhelp) {
|
||||||
givehelp(DEFAULTCALCHELP);
|
givehelp(DEFAULTCALCHELP);
|
||||||
|
libcalc_call_me_last();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,10 +216,7 @@ main(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* check for pipe mode and/or non-tty stdin
|
* check for pipe mode and/or non-tty stdin
|
||||||
*/
|
*/
|
||||||
if (p_flag) {
|
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 */
|
stdin_tty = isatty(0); /* assume stdin is on fd 0 */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,11 +229,9 @@ main(int argc, char **argv)
|
|||||||
* if tty, setup bindings
|
* if tty, setup bindings
|
||||||
*/
|
*/
|
||||||
if (stdin_tty) {
|
if (stdin_tty) {
|
||||||
version(stdout);
|
printf("%s (version %s)\n", CALC_TITLE, version());
|
||||||
printf("[%s]\n\n",
|
printf("[%s]\n\n",
|
||||||
"Type \"exit\" to exit, or \"help\" for help.");
|
"Type \"exit\" to exit, or \"help\" for help.");
|
||||||
}
|
|
||||||
if (stdin_tty) {
|
|
||||||
switch (hist_init(calcbindings)) {
|
switch (hist_init(calcbindings)) {
|
||||||
case HIST_NOFILE:
|
case HIST_NOFILE:
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@@ -232,13 +246,6 @@ main(int argc, char **argv)
|
|||||||
break;
|
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,17 +256,12 @@ main(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* reset/initialize the computing environment
|
* reset/initialize the computing environment
|
||||||
*/
|
*/
|
||||||
post_init = TRUE; /* jmpbuf is ready for math_error() */
|
if (post_init) {
|
||||||
inittokens();
|
initialize();
|
||||||
initglobals();
|
} else {
|
||||||
initfunctions();
|
/* initialize already done, jmpbuf is ready */
|
||||||
initstack();
|
post_init = TRUE;
|
||||||
resetinput();
|
}
|
||||||
math_cleardiversions();
|
|
||||||
math_setfp(stdout);
|
|
||||||
math_setmode(MODE_INITIAL);
|
|
||||||
math_setdigits((long)DISPLAY_DEFAULT);
|
|
||||||
conf->maxprint = MAXPRINT_DEFAULT;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if arg mode or non-tty mode, just do the work and be gone
|
* if arg mode or non-tty mode, just do the work and be gone
|
||||||
@@ -275,149 +277,35 @@ main(int argc, char **argv)
|
|||||||
(void) openterminal();
|
(void) openterminal();
|
||||||
start_done = TRUE;
|
start_done = TRUE;
|
||||||
getcommands(FALSE);
|
getcommands(FALSE);
|
||||||
|
libcalc_call_me_last();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
start_done = TRUE;
|
/* if in arg mode, we should not get here */
|
||||||
|
if (str) {
|
||||||
/*
|
libcalc_call_me_last();
|
||||||
* if in arg mode, we should not get here
|
|
||||||
*/
|
|
||||||
if (str)
|
|
||||||
exit(1);
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* process commands (from stdin, not the command line)
|
* process commands
|
||||||
*/
|
*/
|
||||||
abortlevel = 0;
|
if (!start_done) {
|
||||||
_math_abort_ = FALSE;
|
reinitialize();
|
||||||
inputwait = FALSE;
|
|
||||||
(void) signal(SIGINT, intint);
|
|
||||||
math_cleardiversions();
|
|
||||||
math_setfp(stdout);
|
|
||||||
resetscopes();
|
|
||||||
resetinput();
|
|
||||||
if (q_flag == FALSE && allow_read) {
|
|
||||||
q_flag = TRUE;
|
|
||||||
runrcfiles();
|
|
||||||
}
|
}
|
||||||
(void) openterminal();
|
(void) signal(SIGINT, intint);
|
||||||
|
start_done = TRUE;
|
||||||
getcommands(TRUE);
|
getcommands(TRUE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* all done
|
* all done
|
||||||
*/
|
*/
|
||||||
|
libcalc_call_me_last();
|
||||||
exit(0);
|
exit(0);
|
||||||
/*NOTREACHED*/
|
/*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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interrupt routine.
|
* Interrupt routine.
|
||||||
*
|
*
|
||||||
@@ -438,4 +326,34 @@ intint(int arg)
|
|||||||
printf("\n[Abort level %d]\n", abortlevel);
|
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, "no jmpbuf jumpback point - ABORTING!!!\n");
|
||||||
|
/*
|
||||||
|
* don't call libcalc_call_me_last() -- we might loop
|
||||||
|
* and besides ... this is an unusual internal error case
|
||||||
|
*/
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
56
calc.h
56
calc.h
@@ -1,17 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1995 David I. Bell
|
* Copyright (c) 1997 David I. Bell
|
||||||
* Permission is granted to use, distribute, or modify this source,
|
* Permission is granted to use, distribute, or modify this source,
|
||||||
* provided that this copyright notice remains intact.
|
* provided that this copyright notice remains intact.
|
||||||
*
|
*
|
||||||
* Definitions for calculator program.
|
* 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"
|
#include "value.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -94,20 +93,23 @@ extern int flushall(void);
|
|||||||
extern int idfputstr(FILEID id, char *str);
|
extern int idfputstr(FILEID id, char *str);
|
||||||
extern int rewindid(FILEID id);
|
extern int rewindid(FILEID id);
|
||||||
extern void rewindall(void);
|
extern void rewindall(void);
|
||||||
extern long filesize(FILEID id);
|
extern ZVALUE zfilesize(FILEID id);
|
||||||
extern void showfiles(void);
|
extern void showfiles(void);
|
||||||
extern int fscanfid(FILEID id, char *fmt, int count, VALUE **vals);
|
extern int fscanfid(FILEID id, char *fmt, int count, VALUE **vals);
|
||||||
extern int scanfstr(char *str, char *fmt, int count, VALUE **vals);
|
extern int scanfstr(char *str, char *fmt, int count, VALUE **vals);
|
||||||
extern long ftellid(FILEID id);
|
extern int ftellid(FILEID id, ZVALUE *res);
|
||||||
extern long fseekid(FILEID id, long offset, int whence);
|
extern int fseekid(FILEID id, ZVALUE offset, int whence);
|
||||||
extern int isattyid(FILEID id);
|
extern int isattyid(FILEID id);
|
||||||
long fsearch(FILEID id, char *str, long pos);
|
extern int fsearch(FILEID id, char *str, ZVALUE start, ZVALUE end, ZVALUE *res);
|
||||||
long frsearch(FILEID id, char *str, long pos);
|
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.
|
* Input routines.
|
||||||
*/
|
*/
|
||||||
extern FILE *f_open(char *name, char *mode);
|
|
||||||
extern int openstring(char *str);
|
extern int openstring(char *str);
|
||||||
extern int openterminal(void);
|
extern int openterminal(void);
|
||||||
extern int opensearchfile(char *name, char *pathlist, char *exten, int reopen_ok);
|
extern int opensearchfile(char *name, char *pathlist, char *exten, int reopen_ok);
|
||||||
@@ -121,7 +123,6 @@ extern char *inputname(void);
|
|||||||
extern long linenumber(void);
|
extern long linenumber(void);
|
||||||
extern void runrcfiles(void);
|
extern void runrcfiles(void);
|
||||||
extern void closeinput(void);
|
extern void closeinput(void);
|
||||||
extern FILE *curstream(void);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -131,11 +132,18 @@ extern NUMBER *constvalue(unsigned long index);
|
|||||||
extern long addnumber(char *str);
|
extern long addnumber(char *str);
|
||||||
extern long addqconstant(NUMBER *q);
|
extern long addqconstant(NUMBER *q);
|
||||||
extern void initstack(void);
|
extern void initstack(void);
|
||||||
extern void version(FILE *stream);
|
|
||||||
extern void getcommands(BOOL toplevel);
|
extern void getcommands(BOOL toplevel);
|
||||||
extern void givehelp(char *type);
|
extern void givehelp(char *type);
|
||||||
extern void hash_init(void);
|
|
||||||
extern void libcalc_call_me_first(void);
|
extern void libcalc_call_me_first(void);
|
||||||
|
extern void libcalc_call_me_last(void);
|
||||||
|
extern void showerrors(void);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialization
|
||||||
|
*/
|
||||||
|
extern void initialize(void);
|
||||||
|
extern void reinitialize(void);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -144,7 +152,6 @@ extern void libcalc_call_me_first(void);
|
|||||||
extern int abortlevel; /* current level of aborts */
|
extern int abortlevel; /* current level of aborts */
|
||||||
extern BOOL inputwait; /* TRUE if in a terminal input wait */
|
extern BOOL inputwait; /* TRUE if in a terminal input wait */
|
||||||
extern VALUE *stack; /* execution stack */
|
extern VALUE *stack; /* execution stack */
|
||||||
extern jmp_buf jmpbuf; /* for errors */
|
|
||||||
extern int start_done; /* TRUE => start up processing finished */
|
extern int start_done; /* TRUE => start up processing finished */
|
||||||
extern int dumpnames; /* TRUE => dump names rather than indices */
|
extern int dumpnames; /* TRUE => dump names rather than indices */
|
||||||
|
|
||||||
@@ -153,6 +160,11 @@ extern char *calcrc; /* $CALCRC or default */
|
|||||||
extern char *calcbindings; /* $CALCBINDINGS or default */
|
extern char *calcbindings; /* $CALCBINDINGS or default */
|
||||||
extern char *home; /* $HOME or default */
|
extern char *home; /* $HOME or default */
|
||||||
extern char *shell; /* $SHELL 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 ign_errmax; /* TRUE (-i) => ignore 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_read; /* FALSE => may not open any files for reading */
|
||||||
extern int allow_write; /* FALSE => may not open any files for writing */
|
extern int allow_write; /* FALSE => may not open any files for writing */
|
||||||
@@ -160,6 +172,16 @@ extern int allow_exec; /* FALSE => may not execute any commands */
|
|||||||
|
|
||||||
extern int post_init; /* TRUE => setjmp for math_error is ready */
|
extern int post_init; /* TRUE => setjmp for math_error is ready */
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* END CODE */
|
/*
|
||||||
|
* 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 */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !__CALC_H__ */
|
||||||
|
6
calc.man
6
calc.man
@@ -317,7 +317,7 @@ A :-separated list of directories used to search for
|
|||||||
scripts filenames that do not begin with /, ./ or ~.
|
scripts filenames that do not begin with /, ./ or ~.
|
||||||
.br
|
.br
|
||||||
.sp
|
.sp
|
||||||
Default value: .:./lib:~/lib:${LIBDIR}
|
Default value: ${CALCPATH}
|
||||||
.br
|
.br
|
||||||
.sp
|
.sp
|
||||||
.TP 5
|
.TP 5
|
||||||
@@ -327,7 +327,7 @@ line), calc searches for files along this :-separated
|
|||||||
environment variable.
|
environment variable.
|
||||||
.br
|
.br
|
||||||
.sp
|
.sp
|
||||||
Default value: ${LIBDIR}/startup:~/.calcrc
|
Default value: ${CALCRC}
|
||||||
.br
|
.br
|
||||||
.sp
|
.sp
|
||||||
.TP 5
|
.TP 5
|
||||||
@@ -338,7 +338,7 @@ key bindings from the filename specified
|
|||||||
by this environment variable.
|
by this environment variable.
|
||||||
.br
|
.br
|
||||||
.sp
|
.sp
|
||||||
Default value: ${LIBDIR}/bindings
|
Default value: ${CALCBINDINGS}
|
||||||
.sp
|
.sp
|
||||||
.SH CREDIT
|
.SH CREDIT
|
||||||
\&
|
\&
|
||||||
|
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_UNGETC2 File not open for reading for ungetc
|
||||||
E_UNGETC3 Bad second argument or other error for ungetc
|
E_UNGETC3 Bad second argument or other error for ungetc
|
||||||
E_BIGEXP Exponent too big in scanning
|
E_BIGEXP Exponent too big in scanning
|
||||||
E_ISATTY1 Non-file argument for isatty
|
E_ISATTY1 E_ISATTY1 is no longer used
|
||||||
E_ISATTY2 File not open for isatty
|
E_ISATTY2 E_ISATTY2 is no longer used
|
||||||
E_ACCESS1 Non-string first argument for access
|
E_ACCESS1 Non-string first argument for access
|
||||||
E_ACCESS2 Bad second argument for access
|
E_ACCESS2 Bad second argument for access
|
||||||
E_SEARCH1 Bad first argument for search
|
E_SEARCH1 Bad first argument for search
|
||||||
E_SEARCH2 Bad second argument for search
|
E_SEARCH2 Bad second argument for search
|
||||||
E_SEARCH3 Bad third 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_RSEARCH1 Bad first argument for rsearch
|
||||||
E_RSEARCH2 Bad second argument for rsearch
|
E_RSEARCH2 Bad second argument for rsearch
|
||||||
E_RSEARCH3 Bad third 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_FOPEN3 Too many open files
|
||||||
E_REWIND2 Attempt to rewind a file that is not open
|
E_REWIND2 Attempt to rewind a file that is not open
|
||||||
E_STRERROR1 Bad argument type for strerror
|
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_MATFILL2 Non-matrix first argument-value for matfill
|
||||||
E_MATDIM Non-matrix argument for matdim
|
E_MATDIM Non-matrix argument for matdim
|
||||||
E_MATSUM Non-matrix argument for matsum
|
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_MATTRANS1 Non-matrix argument for mattrans
|
||||||
E_MATTRANS2 Non-two-dimensional matrix for mattrans
|
E_MATTRANS2 Non-two-dimensional matrix for mattrans
|
||||||
E_DET1 Non-matrix argument for det
|
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_RDPERM Operation allowed because calc mode disallows read operations
|
||||||
E_WRPERM Operation allowed because calc mode disallows write operations
|
E_WRPERM Operation allowed because calc mode disallows write operations
|
||||||
E_EXPERM Operation allowed because calc mode disallows exec 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;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
$1 ~ /^[0-9]/ {
|
$1 ~ /^[0-9]+:/ {
|
||||||
if (error > 0) {
|
if (error > 0) {
|
||||||
if (havebuf2) {
|
if (havebuf2) {
|
||||||
print buf2;
|
print buf2;
|
||||||
@@ -71,4 +71,5 @@ END {
|
|||||||
if (error > 0 && havebuf0) {
|
if (error > 0 && havebuf0) {
|
||||||
print buf0;
|
print buf0;
|
||||||
}
|
}
|
||||||
|
exit (error > 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,
|
* Permission is granted to use, distribute, or modify this source,
|
||||||
* provided that this copyright notice remains intact.
|
* provided that this copyright notice remains intact.
|
||||||
*
|
*
|
||||||
* Data structure declarations for extended precision complex arithmetic.
|
* Data structure declarations for extended precision complex arithmetic.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CMATH_H
|
|
||||||
#define CMATH_H
|
#if !defined(__CMATH_H__)
|
||||||
|
#define __CMATH_H__
|
||||||
|
|
||||||
|
|
||||||
#include "qmath.h"
|
#include "qmath.h"
|
||||||
|
|
||||||
@@ -73,8 +75,25 @@ extern COMPLEX *cexp(COMPLEX *c, NUMBER *epsilon);
|
|||||||
extern COMPLEX *cln(COMPLEX *c, NUMBER *epsilon);
|
extern COMPLEX *cln(COMPLEX *c, NUMBER *epsilon);
|
||||||
extern COMPLEX *ccos(COMPLEX *c, NUMBER *epsilon);
|
extern COMPLEX *ccos(COMPLEX *c, NUMBER *epsilon);
|
||||||
extern COMPLEX *csin(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 *cpolar(NUMBER *q1, NUMBER *q2, NUMBER *epsilon);
|
||||||
extern COMPLEX *crel(COMPLEX *c1, COMPLEX *c2);
|
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_;
|
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)) {
|
if (cisreal(c)) {
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
if (!qisneg(c->real)) {
|
if (!qisneg(c->real)) {
|
||||||
|
qfree(r->real);
|
||||||
r->real = qsqrt(c->real, epsilon, R);
|
r->real = qsqrt(c->real, epsilon, R);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
ntmp = qneg(c->real);
|
ntmp = qneg(c->real);
|
||||||
|
qfree(r->imag);
|
||||||
r->imag = qsqrt(ntmp, epsilon, R);
|
r->imag = qsqrt(ntmp, epsilon, R);
|
||||||
qfree(ntmp);
|
qfree(ntmp);
|
||||||
return r;
|
return r;
|
||||||
@@ -160,7 +162,7 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
|
|||||||
return clink(&_czero_);
|
return clink(&_czero_);
|
||||||
}
|
}
|
||||||
aes = qscale(c->imag, -1);
|
aes = qscale(c->imag, -1);
|
||||||
v = qdiv(aes, u);
|
v = qqdiv(aes, u);
|
||||||
qfree(aes);
|
qfree(aes);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
r->real = u;
|
r->real = u;
|
||||||
@@ -170,8 +172,8 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
|
|||||||
#endif
|
#endif
|
||||||
imsign = c->imag->num.sign;
|
imsign = c->imag->num.sign;
|
||||||
es = qsquare(epsilon);
|
es = qsquare(epsilon);
|
||||||
aes = qdiv(c->real, es);
|
aes = qqdiv(c->real, es);
|
||||||
bes = qdiv(c->imag, es);
|
bes = qqdiv(c->imag, es);
|
||||||
qfree(es);
|
qfree(es);
|
||||||
zgcd(aes->den, bes->den, &g);
|
zgcd(aes->den, bes->den, &g);
|
||||||
zequo(bes->den, g, &tmp1);
|
zequo(bes->den, g, &tmp1);
|
||||||
@@ -217,12 +219,14 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
|
|||||||
r = comalloc();
|
r = comalloc();
|
||||||
qtemp = *aes;
|
qtemp = *aes;
|
||||||
qtemp.num.sign = sign;
|
qtemp.num.sign = sign;
|
||||||
|
qfree(r->real);
|
||||||
r->real = qmul(&qtemp, epsilon);
|
r->real = qmul(&qtemp, epsilon);
|
||||||
qfree(aes);
|
qfree(aes);
|
||||||
bes = qscale(r->real, 1);
|
bes = qscale(r->real, 1);
|
||||||
qtemp = *bes;
|
qtemp = *bes;
|
||||||
qtemp.num.sign = sign ^ imsign;
|
qtemp.num.sign = sign ^ imsign;
|
||||||
r->imag = qdiv(c->imag, &qtemp);
|
qfree(r->imag);
|
||||||
|
r->imag = qqdiv(c->imag, &qtemp);
|
||||||
qfree(bes);
|
qfree(bes);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -272,12 +276,14 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
|
|||||||
r = comalloc();
|
r = comalloc();
|
||||||
qtemp = *aes;
|
qtemp = *aes;
|
||||||
qtemp.num.sign = sign;
|
qtemp.num.sign = sign;
|
||||||
|
qfree(r->real);
|
||||||
r->real = qmul(&qtemp, epsilon);
|
r->real = qmul(&qtemp, epsilon);
|
||||||
qfree(aes);
|
qfree(aes);
|
||||||
bes = qscale(r->real, 1);
|
bes = qscale(r->real, 1);
|
||||||
qtemp = *bes;
|
qtemp = *bes;
|
||||||
qtemp.num.sign = sign ^ imsign;
|
qtemp.num.sign = sign ^ imsign;
|
||||||
r->imag = qdiv(c->imag, &qtemp);
|
qfree(r->imag);
|
||||||
|
r->imag = qqdiv(c->imag, &qtemp);
|
||||||
qfree(bes);
|
qfree(bes);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -355,10 +361,10 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
|
|||||||
return clink(&_czero_);
|
return clink(&_czero_);
|
||||||
}
|
}
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
if (!qiszero(u))
|
qfree(r->real);
|
||||||
r->real = u;
|
qfree(r->imag);
|
||||||
if (!qiszero(v))
|
r->real = u;
|
||||||
r->imag = v;
|
r->imag = v;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,6 +390,7 @@ croot(COMPLEX *c, NUMBER *q, NUMBER *epsilon)
|
|||||||
return csqrt(c, epsilon, 24L);
|
return csqrt(c, epsilon, 24L);
|
||||||
if (cisreal(c) && !qisneg(c->real)) {
|
if (cisreal(c) && !qisneg(c->real)) {
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
|
qfree(r->real);
|
||||||
r->real = qroot(c->real, q, epsilon);
|
r->real = qroot(c->real, q, epsilon);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -412,7 +419,7 @@ croot(COMPLEX *c, NUMBER *q, NUMBER *epsilon)
|
|||||||
epsilon2 = qbitvalue(n - m - 4);
|
epsilon2 = qbitvalue(n - m - 4);
|
||||||
tmp1 = qatan2(c->imag, c->real, epsilon2);
|
tmp1 = qatan2(c->imag, c->real, epsilon2);
|
||||||
qfree(epsilon2);
|
qfree(epsilon2);
|
||||||
tmp2 = qdiv(tmp1, q);
|
tmp2 = qqdiv(tmp1, q);
|
||||||
qfree(tmp1);
|
qfree(tmp1);
|
||||||
r = cpolar(root, tmp2, epsilon);
|
r = cpolar(root, tmp2, epsilon);
|
||||||
qfree(root);
|
qfree(root);
|
||||||
@@ -437,8 +444,9 @@ cexp(COMPLEX *c, NUMBER *epsilon)
|
|||||||
math_error("Zero epsilon for cexp");
|
math_error("Zero epsilon for cexp");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
r = comalloc();
|
|
||||||
if (cisreal(c)) {
|
if (cisreal(c)) {
|
||||||
|
r = comalloc();
|
||||||
|
qfree(r->real);
|
||||||
r->real = qexp(c->real, epsilon);
|
r->real = qexp(c->real, epsilon);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -458,11 +466,14 @@ cexp(COMPLEX *c, NUMBER *epsilon)
|
|||||||
qsincos(c->imag, k - n + 2, &sin, &cos);
|
qsincos(c->imag, k - n + 2, &sin, &cos);
|
||||||
tmp2 = qmul(tmp1, cos);
|
tmp2 = qmul(tmp1, cos);
|
||||||
qfree(cos);
|
qfree(cos);
|
||||||
|
r = comalloc();
|
||||||
|
qfree(r->real);
|
||||||
r->real = qmappr(tmp2, epsilon, 24L);
|
r->real = qmappr(tmp2, epsilon, 24L);
|
||||||
qfree(tmp2);
|
qfree(tmp2);
|
||||||
tmp2 = qmul(tmp1, sin);
|
tmp2 = qmul(tmp1, sin);
|
||||||
qfree(tmp1);
|
qfree(tmp1);
|
||||||
qfree(sin);
|
qfree(sin);
|
||||||
|
qfree(r->imag);
|
||||||
r->imag = qmappr(tmp2, epsilon, 24L);
|
r->imag = qmappr(tmp2, epsilon, 24L);
|
||||||
qfree(tmp2);
|
qfree(tmp2);
|
||||||
return r;
|
return r;
|
||||||
@@ -488,6 +499,7 @@ cln(COMPLEX *c, NUMBER *epsilon)
|
|||||||
return clink(&_czero_);
|
return clink(&_czero_);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
if (cisreal(c) && !qisneg(c->real)) {
|
if (cisreal(c) && !qisneg(c->real)) {
|
||||||
|
qfree(r->real);
|
||||||
r->real = qln(c->real, epsilon);
|
r->real = qln(c->real, epsilon);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -500,8 +512,10 @@ cln(COMPLEX *c, NUMBER *epsilon)
|
|||||||
tmp1 = qln(a2b2, epsilon1);
|
tmp1 = qln(a2b2, epsilon1);
|
||||||
qfree(a2b2);
|
qfree(a2b2);
|
||||||
qfree(epsilon1);
|
qfree(epsilon1);
|
||||||
|
qfree(r->real);
|
||||||
r->real = qscale(tmp1, -1L);
|
r->real = qscale(tmp1, -1L);
|
||||||
qfree(tmp1);
|
qfree(tmp1);
|
||||||
|
qfree(r->imag);
|
||||||
r->imag = qatan2(c->imag, c->real, epsilon);
|
r->imag = qatan2(c->imag, c->real, epsilon);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -526,6 +540,8 @@ ccos(COMPLEX *c, NUMBER *epsilon)
|
|||||||
}
|
}
|
||||||
n = qilog2(epsilon);
|
n = qilog2(epsilon);
|
||||||
ctmp1 = comalloc();
|
ctmp1 = comalloc();
|
||||||
|
qfree(ctmp1->real);
|
||||||
|
qfree(ctmp1->imag);
|
||||||
neg = qisneg(c->imag);
|
neg = qisneg(c->imag);
|
||||||
ctmp1->real = neg ? qneg(c->imag) : qlink(c->imag);
|
ctmp1->real = neg ? qneg(c->imag) : qlink(c->imag);
|
||||||
ctmp1->imag = neg ? qlink(c->real) : qneg(c->real);
|
ctmp1->imag = neg ? qlink(c->real) : qneg(c->real);
|
||||||
@@ -544,7 +560,9 @@ ccos(COMPLEX *c, NUMBER *epsilon)
|
|||||||
ctmp1 = cscale(ctmp3, -1);
|
ctmp1 = cscale(ctmp3, -1);
|
||||||
comfree(ctmp3);
|
comfree(ctmp3);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
|
qfree(r->real);
|
||||||
r->real = qmappr(ctmp1->real, epsilon, 24L);
|
r->real = qmappr(ctmp1->real, epsilon, 24L);
|
||||||
|
qfree(r->imag);
|
||||||
r->imag = qmappr(ctmp1->imag, epsilon, 24L);
|
r->imag = qmappr(ctmp1->imag, epsilon, 24L);
|
||||||
comfree(ctmp1);
|
comfree(ctmp1);
|
||||||
return r;
|
return r;
|
||||||
@@ -573,6 +591,8 @@ csin(COMPLEX *c, NUMBER *epsilon)
|
|||||||
n = qilog2(epsilon);
|
n = qilog2(epsilon);
|
||||||
ctmp1 = comalloc();
|
ctmp1 = comalloc();
|
||||||
neg = qisneg(c->imag);
|
neg = qisneg(c->imag);
|
||||||
|
qfree(ctmp1->real);
|
||||||
|
qfree(ctmp1->imag);
|
||||||
ctmp1->real = neg ? qneg(c->imag) : qlink(c->imag);
|
ctmp1->real = neg ? qneg(c->imag) : qlink(c->imag);
|
||||||
ctmp1->imag = neg ? qlink(c->real) : qneg(c->real);
|
ctmp1->imag = neg ? qlink(c->real) : qneg(c->real);
|
||||||
epsilon1 = qbitvalue(n - 2);
|
epsilon1 = qbitvalue(n - 2);
|
||||||
@@ -591,9 +611,11 @@ csin(COMPLEX *c, NUMBER *epsilon)
|
|||||||
comfree(ctmp3);
|
comfree(ctmp3);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
qtmp = neg ? qlink(ctmp1->imag) : qneg(ctmp1->imag);
|
qtmp = neg ? qlink(ctmp1->imag) : qneg(ctmp1->imag);
|
||||||
|
qfree(r->real);
|
||||||
r->real = qmappr(qtmp, epsilon, 24L);
|
r->real = qmappr(qtmp, epsilon, 24L);
|
||||||
qfree(qtmp);
|
qfree(qtmp);
|
||||||
qtmp = neg ? qneg(ctmp1->real) : qlink(ctmp1->real);
|
qtmp = neg ? qneg(ctmp1->real) : qlink(ctmp1->real);
|
||||||
|
qfree(r->imag);
|
||||||
r->imag = qmappr(qtmp, epsilon, 24L);
|
r->imag = qmappr(qtmp, epsilon, 24L);
|
||||||
qfree(qtmp);
|
qfree(qtmp);
|
||||||
comfree(ctmp1);
|
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
|
* Convert a number from polar coordinates to normal complex number form
|
||||||
* within the specified accuracy. This produces the value:
|
* within the specified accuracy. This produces the value:
|
||||||
@@ -625,16 +1005,19 @@ cpolar(NUMBER *q1, NUMBER *q2, NUMBER *epsilon)
|
|||||||
return qlink(&_czero_);
|
return qlink(&_czero_);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
if (qiszero(q2)) {
|
if (qiszero(q2)) {
|
||||||
|
qfree(r->real);
|
||||||
r->real = qlink(q1);
|
r->real = qlink(q1);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
qsincos(q2, m - n + 2, &sin, &cos);
|
qsincos(q2, m - n + 2, &sin, &cos);
|
||||||
tmp = qmul(q1, cos);
|
tmp = qmul(q1, cos);
|
||||||
qfree(cos);
|
qfree(cos);
|
||||||
|
qfree(r->real);
|
||||||
r->real = qmappr(tmp, epsilon, 24L);
|
r->real = qmappr(tmp, epsilon, 24L);
|
||||||
qfree(tmp);
|
qfree(tmp);
|
||||||
tmp = qmul(q1, sin);
|
tmp = qmul(q1, sin);
|
||||||
qfree(sin);
|
qfree(sin);
|
||||||
|
qfree(r->imag);
|
||||||
r->imag = qmappr(tmp, epsilon, 24L);
|
r->imag = qmappr(tmp, epsilon, 24L);
|
||||||
qfree(tmp);
|
qfree(tmp);
|
||||||
return r;
|
return r;
|
||||||
@@ -666,12 +1049,12 @@ cpower(COMPLEX *c1, COMPLEX *c2, NUMBER *epsilon)
|
|||||||
n = qilog2(epsilon);
|
n = qilog2(epsilon);
|
||||||
m1 = m2 = -1000000;
|
m1 = m2 = -1000000;
|
||||||
k1 = k2 = 0;
|
k1 = k2 = 0;
|
||||||
qtmp1 = qsquare(c1->real);
|
|
||||||
qtmp2 = qsquare(c1->imag);
|
|
||||||
a2b2 = qqadd(qtmp1, qtmp2);
|
|
||||||
qfree(qtmp1);
|
|
||||||
qfree(qtmp2);
|
|
||||||
if (!qiszero(c2->real)) {
|
if (!qiszero(c2->real)) {
|
||||||
|
qtmp1 = qsquare(c1->real);
|
||||||
|
qtmp2 = qsquare(c1->imag);
|
||||||
|
a2b2 = qqadd(qtmp1, qtmp2);
|
||||||
|
qfree(qtmp1);
|
||||||
|
qfree(qtmp2);
|
||||||
m1 = qilog2(c2->real);
|
m1 = qilog2(c2->real);
|
||||||
epsilon1 = qbitvalue(-m1 - 1);
|
epsilon1 = qbitvalue(-m1 - 1);
|
||||||
qtmp1 = qln(a2b2, epsilon1);
|
qtmp1 = qln(a2b2, epsilon1);
|
||||||
|
102
commath.c
102
commath.c
@@ -29,10 +29,14 @@ cadd(COMPLEX *c1, COMPLEX *c2)
|
|||||||
if (ciszero(c2))
|
if (ciszero(c2))
|
||||||
return clink(c1);
|
return clink(c1);
|
||||||
r = comalloc();
|
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);
|
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);
|
r->imag = qqadd(c1->imag, c2->imag);
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,10 +54,14 @@ csub(COMPLEX *c1, COMPLEX *c2)
|
|||||||
if (ciszero(c2))
|
if (ciszero(c2))
|
||||||
return clink(c1);
|
return clink(c1);
|
||||||
r = comalloc();
|
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);
|
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);
|
r->imag = qsub(c1->imag, c2->imag);
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +103,9 @@ cmul(COMPLEX *c1, COMPLEX *c2)
|
|||||||
q2 = qmul(c1->real, c2->real);
|
q2 = qmul(c1->real, c2->real);
|
||||||
q3 = qmul(c1->imag, c2->imag);
|
q3 = qmul(c1->imag, c2->imag);
|
||||||
q4 = qqadd(q2, q3);
|
q4 = qqadd(q2, q3);
|
||||||
|
qfree(r->real);
|
||||||
r->real = qsub(q2, q3);
|
r->real = qsub(q2, q3);
|
||||||
|
qfree(r->imag);
|
||||||
r->imag = qsub(q1, q4);
|
r->imag = qsub(q1, q4);
|
||||||
qfree(q1);
|
qfree(q1);
|
||||||
qfree(q2);
|
qfree(q2);
|
||||||
@@ -122,10 +132,12 @@ csquare(COMPLEX *c)
|
|||||||
return clink(&_cnegone_);
|
return clink(&_cnegone_);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
if (cisreal(c)) {
|
if (cisreal(c)) {
|
||||||
|
qfree(r->real);
|
||||||
r->real = qsquare(c->real);
|
r->real = qsquare(c->real);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if (cisimag(c)) {
|
if (cisimag(c)) {
|
||||||
|
qfree(r->real);
|
||||||
q1 = qsquare(c->imag);
|
q1 = qsquare(c->imag);
|
||||||
r->real = qneg(q1);
|
r->real = qneg(q1);
|
||||||
qfree(q1);
|
qfree(q1);
|
||||||
@@ -133,9 +145,11 @@ csquare(COMPLEX *c)
|
|||||||
}
|
}
|
||||||
q1 = qsquare(c->real);
|
q1 = qsquare(c->real);
|
||||||
q2 = qsquare(c->imag);
|
q2 = qsquare(c->imag);
|
||||||
|
qfree(r->real);
|
||||||
r->real = qsub(q1, q2);
|
r->real = qsub(q1, q2);
|
||||||
qfree(q1);
|
qfree(q1);
|
||||||
qfree(q2);
|
qfree(q2);
|
||||||
|
qfree(r->imag);
|
||||||
q1 = qmul(c->real, c->imag);
|
q1 = qmul(c->real, c->imag);
|
||||||
r->imag = qscale(q1, 1L);
|
r->imag = qscale(q1, 1L);
|
||||||
qfree(q1);
|
qfree(q1);
|
||||||
@@ -160,26 +174,32 @@ cdiv(COMPLEX *c1, COMPLEX *c2)
|
|||||||
return clink(&_cone_);
|
return clink(&_cone_);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
if (cisreal(c1) && cisreal(c2)) {
|
if (cisreal(c1) && cisreal(c2)) {
|
||||||
r->real = qdiv(c1->real, c2->real);
|
qfree(r->real);
|
||||||
|
r->real = qqdiv(c1->real, c2->real);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if (cisimag(c1) && cisimag(c2)) {
|
if (cisimag(c1) && cisimag(c2)) {
|
||||||
r->real = qdiv(c1->imag, c2->imag);
|
qfree(r->real);
|
||||||
|
r->real = qqdiv(c1->imag, c2->imag);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if (cisimag(c1) && cisreal(c2)) {
|
if (cisimag(c1) && cisreal(c2)) {
|
||||||
r->imag = qdiv(c1->imag, c2->real);
|
qfree(r->imag);
|
||||||
|
r->imag = qqdiv(c1->imag, c2->real);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if (cisreal(c1) && cisimag(c2)) {
|
if (cisreal(c1) && cisimag(c2)) {
|
||||||
q1 = qdiv(c1->real, c2->imag);
|
qfree(r->imag);
|
||||||
|
q1 = qqdiv(c1->real, c2->imag);
|
||||||
r->imag = qneg(q1);
|
r->imag = qneg(q1);
|
||||||
qfree(q1);
|
qfree(q1);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if (cisreal(c2)) {
|
if (cisreal(c2)) {
|
||||||
r->real = qdiv(c1->real, c2->real);
|
qfree(r->real);
|
||||||
r->imag = qdiv(c1->imag, c2->real);
|
qfree(r->imag);
|
||||||
|
r->real = qqdiv(c1->real, c2->real);
|
||||||
|
r->imag = qqdiv(c1->imag, c2->real);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
q1 = qsquare(c2->real);
|
q1 = qsquare(c2->real);
|
||||||
@@ -192,14 +212,16 @@ cdiv(COMPLEX *c1, COMPLEX *c2)
|
|||||||
q3 = qqadd(q1, q2);
|
q3 = qqadd(q1, q2);
|
||||||
qfree(q1);
|
qfree(q1);
|
||||||
qfree(q2);
|
qfree(q2);
|
||||||
r->real = qdiv(q3, den);
|
qfree(r->real);
|
||||||
|
r->real = qqdiv(q3, den);
|
||||||
qfree(q3);
|
qfree(q3);
|
||||||
q1 = qmul(c1->real, c2->imag);
|
q1 = qmul(c1->real, c2->imag);
|
||||||
q2 = qmul(c1->imag, c2->real);
|
q2 = qmul(c1->imag, c2->real);
|
||||||
q3 = qsub(q2, q1);
|
q3 = qsub(q2, q1);
|
||||||
qfree(q1);
|
qfree(q1);
|
||||||
qfree(q2);
|
qfree(q2);
|
||||||
r->imag = qdiv(q3, den);
|
qfree(r->imag);
|
||||||
|
r->imag = qqdiv(q3, den);
|
||||||
qfree(q3);
|
qfree(q3);
|
||||||
qfree(den);
|
qfree(den);
|
||||||
return r;
|
return r;
|
||||||
@@ -221,11 +243,13 @@ cinv(COMPLEX *c)
|
|||||||
}
|
}
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
if (cisreal(c)) {
|
if (cisreal(c)) {
|
||||||
|
qfree(r->real);
|
||||||
r->real = qinv(c->real);
|
r->real = qinv(c->real);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if (cisimag(c)) {
|
if (cisimag(c)) {
|
||||||
q1 = qinv(c->imag);
|
q1 = qinv(c->imag);
|
||||||
|
qfree(r->imag);
|
||||||
r->imag = qneg(q1);
|
r->imag = qneg(q1);
|
||||||
qfree(q1);
|
qfree(q1);
|
||||||
return r;
|
return r;
|
||||||
@@ -235,8 +259,10 @@ cinv(COMPLEX *c)
|
|||||||
den = qqadd(q1, q2);
|
den = qqadd(q1, q2);
|
||||||
qfree(q1);
|
qfree(q1);
|
||||||
qfree(q2);
|
qfree(q2);
|
||||||
r->real = qdiv(c->real, den);
|
qfree(r->real);
|
||||||
q1 = qdiv(c->imag, den);
|
r->real = qqdiv(c->real, den);
|
||||||
|
q1 = qqdiv(c->imag, den);
|
||||||
|
qfree(r->imag);
|
||||||
r->imag = qneg(q1);
|
r->imag = qneg(q1);
|
||||||
qfree(q1);
|
qfree(q1);
|
||||||
qfree(den);
|
qfree(den);
|
||||||
@@ -255,10 +281,14 @@ cneg(COMPLEX *c)
|
|||||||
if (ciszero(c))
|
if (ciszero(c))
|
||||||
return clink(&_czero_);
|
return clink(&_czero_);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
if (!qiszero(c->real))
|
if (!qiszero(c->real)) {
|
||||||
|
qfree(r->real);
|
||||||
r->real = qneg(c->real);
|
r->real = qneg(c->real);
|
||||||
if (!qiszero(c->imag))
|
}
|
||||||
|
if (!qiszero(c->imag)) {
|
||||||
|
qfree(r->imag);
|
||||||
r->imag = qneg(c->imag);
|
r->imag = qneg(c->imag);
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +305,9 @@ cint(COMPLEX *c)
|
|||||||
if (cisint(c))
|
if (cisint(c))
|
||||||
return clink(c);
|
return clink(c);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
|
qfree(r->real);
|
||||||
r->real = qint(c->real);
|
r->real = qint(c->real);
|
||||||
|
qfree(r->imag);
|
||||||
r->imag = qint(c->imag);
|
r->imag = qint(c->imag);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -293,7 +325,9 @@ cfrac(COMPLEX *c)
|
|||||||
if (cisint(c))
|
if (cisint(c))
|
||||||
return clink(&_czero_);
|
return clink(&_czero_);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
|
qfree(r->real);
|
||||||
r->real = qfrac(c->real);
|
r->real = qfrac(c->real);
|
||||||
|
qfree(r->imag);
|
||||||
r->imag = qfrac(c->imag);
|
r->imag = qfrac(c->imag);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -311,8 +345,11 @@ cconj(COMPLEX *c)
|
|||||||
if (cisreal(c))
|
if (cisreal(c))
|
||||||
return clink(c);
|
return clink(c);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
if (!qiszero(c->real))
|
if (!qiszero(c->real)) {
|
||||||
|
qfree(r->real);
|
||||||
r->real = qlink(c->real);
|
r->real = qlink(c->real);
|
||||||
|
}
|
||||||
|
qfree(r->imag);
|
||||||
r->imag = qneg(c->imag);
|
r->imag = qneg(c->imag);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -329,8 +366,10 @@ creal(COMPLEX *c)
|
|||||||
if (cisreal(c))
|
if (cisreal(c))
|
||||||
return clink(c);
|
return clink(c);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
if (!qiszero(c->real))
|
if (!qiszero(c->real)) {
|
||||||
|
qfree(r->real);
|
||||||
r->real = qlink(c->real);
|
r->real = qlink(c->real);
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,6 +385,7 @@ cimag(COMPLEX *c)
|
|||||||
if (cisreal(c))
|
if (cisreal(c))
|
||||||
return clink(&_czero_);
|
return clink(&_czero_);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
|
qfree(r->real);
|
||||||
r->real = qlink(c->imag);
|
r->real = qlink(c->imag);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -362,6 +402,8 @@ caddq(COMPLEX *c, NUMBER *q)
|
|||||||
if (qiszero(q))
|
if (qiszero(q))
|
||||||
return clink(c);
|
return clink(c);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
|
qfree(r->real);
|
||||||
|
qfree(r->imag);
|
||||||
r->real = qqadd(c->real, q);
|
r->real = qqadd(c->real, q);
|
||||||
r->imag = qlink(c->imag);
|
r->imag = qlink(c->imag);
|
||||||
return r;
|
return r;
|
||||||
@@ -379,6 +421,8 @@ csubq(COMPLEX *c, NUMBER *q)
|
|||||||
if (qiszero(q))
|
if (qiszero(q))
|
||||||
return clink(c);
|
return clink(c);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
|
qfree(r->real);
|
||||||
|
qfree(r->imag);
|
||||||
r->real = qsub(c->real, q);
|
r->real = qsub(c->real, q);
|
||||||
r->imag = qlink(c->imag);
|
r->imag = qlink(c->imag);
|
||||||
return r;
|
return r;
|
||||||
@@ -397,6 +441,8 @@ cshift(COMPLEX *c, long n)
|
|||||||
if (ciszero(c) || (n == 0))
|
if (ciszero(c) || (n == 0))
|
||||||
return clink(c);
|
return clink(c);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
|
qfree(r->real);
|
||||||
|
qfree(r->imag);
|
||||||
r->real = qshift(c->real, n);
|
r->real = qshift(c->real, n);
|
||||||
r->imag = qshift(c->imag, n);
|
r->imag = qshift(c->imag, n);
|
||||||
return r;
|
return r;
|
||||||
@@ -414,6 +460,8 @@ cscale(COMPLEX *c, long n)
|
|||||||
if (ciszero(c) || (n == 0))
|
if (ciszero(c) || (n == 0))
|
||||||
return clink(c);
|
return clink(c);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
|
qfree(r->real);
|
||||||
|
qfree(r->imag);
|
||||||
r->real = qscale(c->real, n);
|
r->real = qscale(c->real, n);
|
||||||
r->imag = qscale(c->imag, n);
|
r->imag = qscale(c->imag, n);
|
||||||
return r;
|
return r;
|
||||||
@@ -435,6 +483,8 @@ cmulq(COMPLEX *c, NUMBER *q)
|
|||||||
if (qisnegone(q))
|
if (qisnegone(q))
|
||||||
return cneg(c);
|
return cneg(c);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
|
qfree(r->real);
|
||||||
|
qfree(r->imag);
|
||||||
r->real = qmul(c->real, q);
|
r->real = qmul(c->real, q);
|
||||||
r->imag = qmul(c->imag, q);
|
r->imag = qmul(c->imag, q);
|
||||||
return r;
|
return r;
|
||||||
@@ -458,8 +508,10 @@ cdivq(COMPLEX *c, NUMBER *q)
|
|||||||
if (qisnegone(q))
|
if (qisnegone(q))
|
||||||
return cneg(c);
|
return cneg(c);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
r->real = qdiv(c->real, q);
|
qfree(r->real);
|
||||||
r->imag = qdiv(c->imag, q);
|
qfree(r->imag);
|
||||||
|
r->real = qqdiv(c->real, q);
|
||||||
|
r->imag = qqdiv(c->imag, q);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,10 +529,10 @@ qqtoc(NUMBER *q1, NUMBER *q2)
|
|||||||
if (qiszero(q1) && qiszero(q2))
|
if (qiszero(q1) && qiszero(q2))
|
||||||
return clink(&_czero_);
|
return clink(&_czero_);
|
||||||
r = comalloc();
|
r = comalloc();
|
||||||
if (!qiszero(q1))
|
qfree(r->real);
|
||||||
r->real = qlink(q1);
|
qfree(r->imag);
|
||||||
if (!qiszero(q2))
|
r->real = qlink(q1);
|
||||||
r->imag = qlink(q2);
|
r->imag = qlink(q2);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,6 +564,8 @@ crel(COMPLEX *c1, COMPLEX *c2)
|
|||||||
COMPLEX *c;
|
COMPLEX *c;
|
||||||
|
|
||||||
c = comalloc();
|
c = comalloc();
|
||||||
|
qfree(c->real);
|
||||||
|
qfree(c->imag);
|
||||||
c->real = itoq((long) qrel(c1->real, c2->real));
|
c->real = itoq((long) qrel(c1->real, c2->real));
|
||||||
c->imag = itoq((long) qrel(c1->imag, c2->imag));
|
c->imag = itoq((long) qrel(c1->imag, c2->imag));
|
||||||
|
|
||||||
|
305
config.c
305
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,
|
* Permission is granted to use, distribute, or modify this source,
|
||||||
* provided that this copyright notice remains intact.
|
* provided that this copyright notice remains intact.
|
||||||
*
|
*
|
||||||
* Configuration routines.
|
* Configuration routines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "calc.h"
|
#include "calc.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "zrand.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},
|
{"round", CONFIG_ROUND},
|
||||||
{"leadzero", CONFIG_LEADZERO},
|
{"leadzero", CONFIG_LEADZERO},
|
||||||
{"fullzero", CONFIG_FULLZERO},
|
{"fullzero", CONFIG_FULLZERO},
|
||||||
{"maxerr", CONFIG_MAXERR},
|
{"maxscan", CONFIG_MAXSCAN},
|
||||||
|
{"maxerr", CONFIG_MAXSCAN}, /* old name for maxscan */
|
||||||
{"prompt", CONFIG_PROMPT},
|
{"prompt", CONFIG_PROMPT},
|
||||||
{"more", CONFIG_MORE},
|
{"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}
|
{NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -74,10 +86,16 @@ CONFIG oldstd = { /* backward compatible standard configuration */
|
|||||||
24, /* round()/bround() default rounding mode */
|
24, /* round()/bround() default rounding mode */
|
||||||
FALSE, /* ok to print leading 0 before decimal pt */
|
FALSE, /* ok to print leading 0 before decimal pt */
|
||||||
0, /* ok to print trailing 0's */
|
0, /* ok to print trailing 0's */
|
||||||
MAXERRORCOUNT, /* max errors before abort */
|
MAXSCANCOUNT, /* max scan errors before abort */
|
||||||
PROMPT1, /* normal prompt */
|
PROMPT1, /* normal prompt */
|
||||||
PROMPT2, /* prompt when inside multi-line input */
|
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 */
|
||||||
|
0, /* calc library debug level */
|
||||||
|
0, /* internal calc debug level */
|
||||||
|
0 /* user defined debug level */
|
||||||
};
|
};
|
||||||
CONFIG newstd = { /* new non-backward compatible configuration */
|
CONFIG newstd = { /* new non-backward compatible configuration */
|
||||||
MODE_INITIAL, /* current output mode */
|
MODE_INITIAL, /* current output mode */
|
||||||
@@ -103,10 +121,16 @@ CONFIG newstd = { /* new non-backward compatible configuration */
|
|||||||
24, /* round()/bround() default rounding mode */
|
24, /* round()/bround() default rounding mode */
|
||||||
TRUE, /* ok to print leading 0 before decimal pt */
|
TRUE, /* ok to print leading 0 before decimal pt */
|
||||||
1, /* ok to print trailing 0's */
|
1, /* ok to print trailing 0's */
|
||||||
MAXERRORCOUNT, /* max errors before abort */
|
MAXSCANCOUNT, /* max scan errors before abort */
|
||||||
"; ", /* normal prompt */
|
"; ", /* normal prompt */
|
||||||
";; ", /* prompt when inside multi-line input */
|
";; ", /* 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 */
|
||||||
|
0, /* calc library debug level */
|
||||||
|
0, /* internal calc debug level */
|
||||||
|
0 /* user defined debug level */
|
||||||
};
|
};
|
||||||
CONFIG *conf = NULL; /* loaded in at startup - current configuration */
|
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
|
* declate static functions
|
||||||
*/
|
*/
|
||||||
static int modetype(char *name);
|
static int modetype(char *name);
|
||||||
|
static int blkbase(char *name);
|
||||||
|
static int blkfmt(char *name);
|
||||||
static int truthtype(char *name);
|
static int truthtype(char *name);
|
||||||
static char *modename(int type);
|
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.
|
* Given the name of a truth value, convert it to a BOOL or -1.
|
||||||
* Returns -1 if the string is unknown.
|
* Returns -1 if the string is unknown.
|
||||||
@@ -257,9 +360,9 @@ setconfig(int type, VALUE *vp)
|
|||||||
case CONFIG_ALL:
|
case CONFIG_ALL:
|
||||||
newconf = NULL; /* firewall */
|
newconf = NULL; /* firewall */
|
||||||
if (vp->v_type == V_STR) {
|
if (vp->v_type == V_STR) {
|
||||||
if (strcmp(vp->v_str, "oldstd") == 0) {
|
if (strcmp(vp->v_str->s_str, "oldstd") == 0) {
|
||||||
newconf = &oldstd;
|
newconf = &oldstd;
|
||||||
} else if (strcmp(vp->v_str, "newstd") == 0) {
|
} else if (strcmp(vp->v_str->s_str, "newstd") == 0) {
|
||||||
newconf = &newstd;
|
newconf = &newstd;
|
||||||
} else {
|
} else {
|
||||||
math_error("CONFIG alias not oldstd or newstd");
|
math_error("CONFIG alias not oldstd or newstd");
|
||||||
@@ -311,7 +414,7 @@ setconfig(int type, VALUE *vp)
|
|||||||
math_error("Non-string for mode");
|
math_error("Non-string for mode");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
temp = modetype(vp->v_str);
|
temp = modetype(vp->v_str->s_str);
|
||||||
if (temp < 0) {
|
if (temp < 0) {
|
||||||
math_error("Unknown mode \"%s\"", vp->v_str);
|
math_error("Unknown mode \"%s\"", vp->v_str);
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
@@ -415,15 +518,14 @@ setconfig(int type, VALUE *vp)
|
|||||||
conf->redc2 = (int)temp;
|
conf->redc2 = (int)temp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case CONFIG_TILDE:
|
case CONFIG_TILDE:
|
||||||
if (vp->v_type == V_NUM) {
|
if (vp->v_type == V_NUM) {
|
||||||
q = vp->v_num;
|
q = vp->v_num;
|
||||||
conf->tilde_ok = !qiszero(q);
|
conf->tilde_ok = !qiszero(q);
|
||||||
} else if (vp->v_type == V_STR) {
|
} else if (vp->v_type == V_STR) {
|
||||||
temp = truthtype(vp->v_str);
|
temp = truthtype(vp->v_str->s_str);
|
||||||
if (temp < 0) {
|
if (temp < 0) {
|
||||||
math_error("Illegal truth value");
|
math_error("Illegal truth value for tilde");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
conf->tilde_ok = (int)temp;
|
conf->tilde_ok = (int)temp;
|
||||||
@@ -435,9 +537,9 @@ setconfig(int type, VALUE *vp)
|
|||||||
q = vp->v_num;
|
q = vp->v_num;
|
||||||
conf->tab_ok = !qiszero(q);
|
conf->tab_ok = !qiszero(q);
|
||||||
} else if (vp->v_type == V_STR) {
|
} else if (vp->v_type == V_STR) {
|
||||||
temp = truthtype(vp->v_str);
|
temp = truthtype(vp->v_str->s_str);
|
||||||
if (temp < 0) {
|
if (temp < 0) {
|
||||||
math_error("Illegal truth value");
|
math_error("Illegal truth value for tab");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
conf->tab_ok = (int)temp;
|
conf->tab_ok = (int)temp;
|
||||||
@@ -575,9 +677,9 @@ setconfig(int type, VALUE *vp)
|
|||||||
q = vp->v_num;
|
q = vp->v_num;
|
||||||
conf->leadzero = !qiszero(q);
|
conf->leadzero = !qiszero(q);
|
||||||
} else if (vp->v_type == V_STR) {
|
} else if (vp->v_type == V_STR) {
|
||||||
temp = truthtype(vp->v_str);
|
temp = truthtype(vp->v_str->s_str);
|
||||||
if (temp < 0) { {
|
if (temp < 0) { {
|
||||||
math_error("Illegal truth value");
|
math_error("Illegal truth value for leadzero");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -590,9 +692,9 @@ setconfig(int type, VALUE *vp)
|
|||||||
q = vp->v_num;
|
q = vp->v_num;
|
||||||
conf->fullzero = !qiszero(q);
|
conf->fullzero = !qiszero(q);
|
||||||
} else if (vp->v_type == V_STR) {
|
} else if (vp->v_type == V_STR) {
|
||||||
temp = truthtype(vp->v_str);
|
temp = truthtype(vp->v_str->s_str);
|
||||||
if (temp < 0) { {
|
if (temp < 0) { {
|
||||||
math_error("Illegal truth value");
|
math_error("Illegal truth value for fullzero");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -600,9 +702,9 @@ setconfig(int type, VALUE *vp)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONFIG_MAXERR:
|
case CONFIG_MAXSCAN:
|
||||||
if (vp->v_type != V_NUM) {
|
if (vp->v_type != V_NUM) {
|
||||||
math_error("Non-numeric for maxerr");
|
math_error("Non-numeric for maxscancount");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
q = vp->v_num;
|
q = vp->v_num;
|
||||||
@@ -610,10 +712,10 @@ setconfig(int type, VALUE *vp)
|
|||||||
if (qisfrac(q) || qisneg(q) || !zistiny(q->num))
|
if (qisfrac(q) || qisneg(q) || !zistiny(q->num))
|
||||||
temp = -1;
|
temp = -1;
|
||||||
if (temp < 0) {
|
if (temp < 0) {
|
||||||
math_error("Maxerr value is out of range");
|
math_error("Maxscan value is out of range");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
conf->maxerrorcount = temp;
|
conf->maxscancount = temp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONFIG_PROMPT:
|
case CONFIG_PROMPT:
|
||||||
@@ -621,12 +723,12 @@ setconfig(int type, VALUE *vp)
|
|||||||
math_error("Non-string for prompt");
|
math_error("Non-string for prompt");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
p = (char *)malloc(strlen(vp->v_str) + 1);
|
p = (char *)malloc(vp->v_str->s_len + 1);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
math_error("Cannot duplicate new prompt");
|
math_error("Cannot duplicate new prompt");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
strcpy(p, vp->v_str);
|
strcpy(p, vp->v_str->s_str);
|
||||||
free(conf->prompt1);
|
free(conf->prompt1);
|
||||||
conf->prompt1 = p;
|
conf->prompt1 = p;
|
||||||
break;
|
break;
|
||||||
@@ -636,30 +738,114 @@ setconfig(int type, VALUE *vp)
|
|||||||
math_error("Non-string for more prompt");
|
math_error("Non-string for more prompt");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
p = (char *)malloc(strlen(vp->v_str) + 1);
|
p = (char *)malloc(vp->v_str->s_len + 1);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
math_error("Cannot duplicate new more prompt");
|
math_error("Cannot duplicate new more prompt");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
strcpy(p, vp->v_str);
|
strcpy(p, vp->v_str->s_str);
|
||||||
free(conf->prompt2);
|
free(conf->prompt2);
|
||||||
conf->prompt2 = p;
|
conf->prompt2 = p;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONFIG_RANDOM:
|
case CONFIG_BLKMAXPRINT:
|
||||||
if (vp->v_type != V_NUM) {
|
if (vp->v_type != V_NUM) {
|
||||||
math_error("Non-numeric for random config value");
|
math_error("Non-numeric for blkmaxprint");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
q = vp->v_num;
|
q = vp->v_num;
|
||||||
temp = qtoi(q);
|
temp = qtoi(q);
|
||||||
if (qisfrac(q) || qisneg(q) || !zistiny(q->num))
|
if (qisfrac(q) || qisneg(q) || !zistiny(q->num))
|
||||||
temp = -1;
|
temp = -1;
|
||||||
if (temp < BLUM_CFG_MIN || temp > BLUM_CFG_MAX) {
|
if (temp < 0) {
|
||||||
math_error("Random config value is out of range");
|
math_error("Blkmaxprint value is out of range");
|
||||||
/*NOTREACHED*/
|
/*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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -676,7 +862,7 @@ setconfig(int type, VALUE *vp)
|
|||||||
* src copy this configuration
|
* src copy this configuration
|
||||||
*
|
*
|
||||||
* returns:
|
* returns:
|
||||||
* prointer to the configuration copy
|
* pointer to the configuration copy
|
||||||
*/
|
*/
|
||||||
CONFIG *
|
CONFIG *
|
||||||
config_copy(CONFIG *src)
|
config_copy(CONFIG *src)
|
||||||
@@ -747,7 +933,7 @@ config_free(CONFIG *cfg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* free prointer values
|
* free pointer values
|
||||||
*/
|
*/
|
||||||
if (cfg->epsilon != NULL) {
|
if (cfg->epsilon != NULL) {
|
||||||
qfree(cfg->epsilon);
|
qfree(cfg->epsilon);
|
||||||
@@ -812,8 +998,7 @@ config_value(CONFIG *cfg, int type, VALUE *vp)
|
|||||||
|
|
||||||
case CONFIG_MODE:
|
case CONFIG_MODE:
|
||||||
vp->v_type = V_STR;
|
vp->v_type = V_STR;
|
||||||
vp->v_subtype = V_STRLITERAL;
|
vp->v_str = makenewstring(modename(cfg->outmode));
|
||||||
vp->v_str = modename(cfg->outmode);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CONFIG_EPSILON:
|
case CONFIG_EPSILON:
|
||||||
@@ -892,24 +1077,46 @@ config_value(CONFIG *cfg, int type, VALUE *vp)
|
|||||||
i = cfg->fullzero;
|
i = cfg->fullzero;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONFIG_MAXERR:
|
case CONFIG_MAXSCAN:
|
||||||
i = cfg->maxerrorcount;
|
i = cfg->maxscancount;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONFIG_PROMPT:
|
case CONFIG_PROMPT:
|
||||||
vp->v_type = V_STR;
|
vp->v_type = V_STR;
|
||||||
vp->v_subtype = V_STRLITERAL;
|
vp->v_str = makenewstring(cfg->prompt1);
|
||||||
vp->v_str = cfg->prompt1;
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CONFIG_MORE:
|
case CONFIG_MORE:
|
||||||
vp->v_type = V_STR;
|
vp->v_type = V_STR;
|
||||||
vp->v_subtype = V_STRLITERAL;
|
vp->v_str = makenewstring(cfg->prompt2);
|
||||||
vp->v_str = cfg->prompt2;
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CONFIG_RANDOM:
|
case CONFIG_BLKMAXPRINT:
|
||||||
i = cfg->random;
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -978,8 +1185,14 @@ config_cmp(CONFIG *cfg1, CONFIG *cfg2)
|
|||||||
cfg1->round != cfg2->round ||
|
cfg1->round != cfg2->round ||
|
||||||
cfg1->leadzero != cfg2->leadzero ||
|
cfg1->leadzero != cfg2->leadzero ||
|
||||||
cfg1->fullzero != cfg2->fullzero ||
|
cfg1->fullzero != cfg2->fullzero ||
|
||||||
cfg1->maxerrorcount != cfg2->maxerrorcount ||
|
cfg1->maxscancount != cfg2->maxscancount ||
|
||||||
strcmp(cfg1->prompt1, cfg2->prompt1) != 0 ||
|
strcmp(cfg1->prompt1, cfg2->prompt1) != 0 ||
|
||||||
strcmp(cfg1->prompt2, cfg2->prompt2) != 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;
|
||||||
}
|
}
|
||||||
|
50
config.h
50
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
|
* Permission to use, copy, modify, and distribute this software and
|
||||||
* its documentation for any purpose and without fee is hereby granted,
|
* its documentation for any purpose and without fee is hereby granted,
|
||||||
@@ -36,9 +36,12 @@
|
|||||||
* 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"
|
#include "qmath.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -69,10 +72,16 @@
|
|||||||
#define CONFIG_ROUND 20
|
#define CONFIG_ROUND 20
|
||||||
#define CONFIG_LEADZERO 21
|
#define CONFIG_LEADZERO 21
|
||||||
#define CONFIG_FULLZERO 22
|
#define CONFIG_FULLZERO 22
|
||||||
#define CONFIG_MAXERR 23
|
#define CONFIG_MAXSCAN 23
|
||||||
#define CONFIG_PROMPT 24
|
#define CONFIG_PROMPT 24
|
||||||
#define CONFIG_MORE 25
|
#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
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -84,11 +93,19 @@
|
|||||||
#define NEW_EPSILON_DEFAULT "1e-10" /* newstd EPSILON_DEFAULT */
|
#define NEW_EPSILON_DEFAULT "1e-10" /* newstd EPSILON_DEFAULT */
|
||||||
#define NEW_EPSILONPREC_DEFAULT 34 /* 34 ==> 2^-34 <= 1e-10 < 2^-33 */
|
#define NEW_EPSILONPREC_DEFAULT 34 /* 34 ==> 2^-34 <= 1e-10 < 2^-33 */
|
||||||
#define MAXPRINT_DEFAULT 16 /* default number of elements printed */
|
#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 */
|
||||||
|
|
||||||
|
#define ERRMAX 20 /* default errmax value */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* configuration object
|
* 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 {
|
struct config {
|
||||||
int outmode; /* current output mode */
|
int outmode; /* current output mode */
|
||||||
@@ -113,11 +130,17 @@ struct config {
|
|||||||
long outround; /* output default rounding mode */
|
long outround; /* output default rounding mode */
|
||||||
long round; /* round()/bround() default rounding mode */
|
long round; /* round()/bround() default rounding mode */
|
||||||
int leadzero; /* ok to print leading 0 before decimal pt */
|
int leadzero; /* ok to print leading 0 before decimal pt */
|
||||||
int fullzero; /* ok to print trailing 0's -- XXX ??? */
|
int fullzero; /* ok to print trailing 0's */
|
||||||
long maxerrorcount; /* max errors before abort */
|
long maxscancount; /* max scan errors before abort */
|
||||||
char *prompt1; /* normal prompt */
|
char *prompt1; /* normal prompt */
|
||||||
char *prompt2; /* prompt when inside multi-line input */
|
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;
|
typedef struct config CONFIG;
|
||||||
|
|
||||||
@@ -131,13 +154,14 @@ extern CONFIG newstd; /* new non-backward compatible configuration */
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* configuration functions
|
* configuration externals
|
||||||
*/
|
*/
|
||||||
extern CONFIG *config_copy(CONFIG *src);
|
extern CONFIG *config_copy(CONFIG *src);
|
||||||
extern void config_free(CONFIG *cfg);
|
extern void config_free(CONFIG *cfg);
|
||||||
extern void config_print(CONFIG *cfg);
|
extern void config_print(CONFIG *cfg);
|
||||||
extern BOOL config_cmp(CONFIG *cfg1, CONFIG *cfg2);
|
extern int configtype(char*);
|
||||||
extern int configtype(char *name);
|
extern void config_print(CONFIG*);
|
||||||
|
extern BOOL config_cmp(CONFIG*, CONFIG*);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif /* !__CONFIG_H__ */
|
||||||
|
167
const.c
167
const.c
@@ -1,27 +1,44 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1993 David I. Bell
|
* Copyright (c) 1997 David I. Bell
|
||||||
* Permission is granted to use, distribute, or modify this source,
|
* Permission is granted to use, distribute, or modify this source,
|
||||||
* provided that this copyright notice remains intact.
|
* provided that this copyright notice remains intact.
|
||||||
*
|
*
|
||||||
* Constant number storage module.
|
* Constant number storage module.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "calc.h"
|
#include "calc.h"
|
||||||
|
#include "qmath.h"
|
||||||
|
|
||||||
#define CONSTALLOCSIZE 400 /* number of constants to allocate */
|
#define CONSTALLOCSIZE 400 /* number of constants to allocate */
|
||||||
|
|
||||||
|
|
||||||
static long constcount; /* number of constants defined */
|
static long constcount; /* number of constants defined */
|
||||||
static long constavail; /* number of constants available */
|
static long constavail; /* number of constants available */
|
||||||
static NUMBER **consttable; /* table of constants */
|
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 < 8; i++)
|
||||||
|
consttable[i] = initnumbs[i];
|
||||||
|
constcount = 8;
|
||||||
|
constavail = CONSTALLOCSIZE - 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
* creating a new entry if necessary. The incoming number is a string
|
||||||
* value which must have a correct format, otherwise an undefined number
|
* value which must have a correct format.
|
||||||
* will result. Returns the index of the number in the constant table.
|
* Returns the index of the number in the constant table.
|
||||||
* Returns zero if the number could not be saved.
|
|
||||||
*
|
*
|
||||||
* given:
|
* given:
|
||||||
* str string representation of number
|
* str string representation of number
|
||||||
@@ -32,8 +49,6 @@ addnumber(char *str)
|
|||||||
NUMBER *q;
|
NUMBER *q;
|
||||||
|
|
||||||
q = str2q(str);
|
q = str2q(str);
|
||||||
if (q == NULL)
|
|
||||||
return 0;
|
|
||||||
return addqconstant(q);
|
return addqconstant(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,14 +74,53 @@ addqconstant(NUMBER *q)
|
|||||||
long denlen; /* denominator length */
|
long denlen; /* denominator length */
|
||||||
HALF numlow; /* bottom value of numerator */
|
HALF numlow; /* bottom value of numerator */
|
||||||
HALF denlow; /* bottom value of denominator */
|
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;
|
numlen = q->num.len;
|
||||||
denlen = q->den.len;
|
denlen = q->den.len;
|
||||||
numlow = q->num.v[0];
|
numlow = q->num.v[0];
|
||||||
denlow = q->den.v[0];
|
denlow = q->den.v[0];
|
||||||
tp = &consttable[1];
|
first = 0;
|
||||||
for (index = 1; index <= constcount; index++) {
|
havefirst = FALSE;
|
||||||
t = *tp++;
|
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]))
|
if ((numlen != t->num.len) || (numlow != t->num.v[0]))
|
||||||
continue;
|
continue;
|
||||||
if ((denlen != t->den.len) || (denlow != t->den.v[0]))
|
if ((denlen != t->den.len) || (denlow != t->den.v[0]))
|
||||||
@@ -74,40 +128,95 @@ addqconstant(NUMBER *q)
|
|||||||
if (q->num.sign != t->num.sign)
|
if (q->num.sign != t->num.sign)
|
||||||
continue;
|
continue;
|
||||||
if (qcmp(q, t) == 0) {
|
if (qcmp(q, t) == 0) {
|
||||||
|
t->links++;
|
||||||
qfree(q);
|
qfree(q);
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (constavail <= 0) {
|
if (havefirst) {
|
||||||
if (consttable == NULL) {
|
consttable[first] = q;
|
||||||
tp = (NUMBER **)
|
return first;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
constavail--;
|
constavail--;
|
||||||
constcount++;
|
consttable[constcount++] = q;
|
||||||
consttable[constcount] = q;
|
return index;
|
||||||
return constcount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the value of a constant number given its 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 *
|
NUMBER *
|
||||||
constvalue(unsigned long index)
|
constvalue(unsigned long index)
|
||||||
{
|
{
|
||||||
if ((index <= 0) || (index > constcount))
|
if (index >= constcount) {
|
||||||
return NULL;
|
math_error("Bad index value for constvalue");
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
if (consttable[index]->links == 0) {
|
||||||
|
math_error("Constvalue has been freed!!!");
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
return consttable[index];
|
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)
|
||||||
|
{
|
||||||
|
NUMBER **qp;
|
||||||
|
|
||||||
|
qp = &consttable[constcount];
|
||||||
|
while (constcount > 0 && (*--qp)->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 */
|
/* END CODE */
|
||||||
|
220
custom.c
Normal file
220
custom.c
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* chongo@toad.com
|
||||||
|
* ...!{pyramid,sun,uunet}!hoptoad!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 */
|
||||||
|
}
|
89
custom.h
Normal file
89
custom.h
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* chongo@toad.com
|
||||||
|
* ...!{pyramid,sun,uunet}!hoptoad!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 /\../\ chongo@toad.com
|
||||||
|
|
||||||
|
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.
|
649
custom/Makefile
Normal file
649
custom/Makefile
Normal file
@@ -0,0 +1,649 @@
|
|||||||
|
#
|
||||||
|
# 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
|
||||||
|
#
|
||||||
|
# chongo@toad.com
|
||||||
|
# ...!{pyramid,sun,uunet}!hoptoad!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
|
||||||
|
|
||||||
|
# The custom help files to install
|
||||||
|
#
|
||||||
|
# Put your custom help files here.
|
||||||
|
#
|
||||||
|
CUSTOM_HELP= argv devnull help sysinfo
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
#-=-=-=-=-=-=- 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; \
|
||||||
|
sccs edit Makefile; \
|
||||||
|
mv Makefile.tmp Makefile; \
|
||||||
|
echo new 'custom Makefile formed -- you need to check it in'; \
|
||||||
|
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}; 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_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_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 /\../\ chongo@toad.com
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* 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";
|
||||||
|
}
|
162
custom/c_argv.c
Normal file
162
custom/c_argv.c
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* chongo@toad.com
|
||||||
|
* ...!{pyramid,sun,uunet}!hoptoad!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 */
|
53
custom/c_devnull.c
Normal file
53
custom/c_devnull.c
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.
|
||||||
|
*
|
||||||
|
* Comments, suggestions, bug fixes and questions about these routines
|
||||||
|
* are welcome. Send EMail to the address given below.
|
||||||
|
*
|
||||||
|
* Happy bit twiddling,
|
||||||
|
*
|
||||||
|
* Landon Curt Noll
|
||||||
|
*
|
||||||
|
* chongo@toad.com
|
||||||
|
* ...!{pyramid,sun,uunet}!hoptoad!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 */
|
77
custom/c_help.c
Normal file
77
custom/c_help.c
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* chongo@toad.com
|
||||||
|
* ...!{pyramid,sun,uunet}!hoptoad!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 */
|
366
custom/c_sysinfo.c
Normal file
366
custom/c_sysinfo.c
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* chongo@toad.com
|
||||||
|
* ...!{pyramid,sun,uunet}!hoptoad!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},
|
||||||
|
{"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},
|
||||||
|
{"PATHSIZE", "max length of path name", NULL, (FULL)PATHSIZE},
|
||||||
|
{"PATHSIZE", "max length of path name", NULL, (FULL)PATHSIZE},
|
||||||
|
{"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)+1);
|
||||||
|
for (q = (char *)vals[0]->v_str, r = buf; *q; ++q, ++r) {
|
||||||
|
if (isascii(*q) && islower(*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 = (STRING *)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 */
|
119
custom/custtbl.c
Normal file
119
custom/custtbl.c
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* chongo@toad.com
|
||||||
|
* ...!{pyramid,sun,uunet}!hoptoad!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**);
|
||||||
|
|
||||||
|
|
||||||
|
#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 },
|
||||||
|
|
||||||
|
|
||||||
|
#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 /\../\ chongo@toad.com
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* 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
|
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
|
7
endian.c
7
endian.c
@@ -66,12 +66,13 @@ main(void)
|
|||||||
/* Determine byte order */
|
/* Determine byte order */
|
||||||
if (intp[0] == 0x12364859) {
|
if (intp[0] == 0x12364859) {
|
||||||
/* Most Significant Byte first */
|
/* Most Significant Byte first */
|
||||||
printf("#define BYTE_ORDER\tBIG_ENDIAN\n");
|
printf("#define CALC_BYTE_ORDER\tBIG_ENDIAN\n");
|
||||||
} else if (intp[0] == 0x59483612) {
|
} else if (intp[0] == 0x59483612) {
|
||||||
/* Least Significant Byte first */
|
/* Least Significant Byte first */
|
||||||
printf("#define BYTE_ORDER\tLITTLE_ENDIAN\n");
|
printf("#define CALC_BYTE_ORDER\tLITTLE_ENDIAN\n");
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unknown int Byte Order, set BYTE_ORDER in Makefile\n");
|
fprintf(stderr,
|
||||||
|
"Unknown int Byte Order, set CALC_BYTE_ORDER in Makefile\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(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,
|
* Permission is granted to use, distribute, or modify this source,
|
||||||
* provided that this copyright notice remains intact.
|
* provided that this copyright notice remains intact.
|
||||||
*
|
*
|
||||||
* File I/O routines callable by users.
|
* File I/O routines callable by users.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(__FILE_H__)
|
||||||
|
#define __FILE_H__
|
||||||
|
|
||||||
|
|
||||||
#include "have_fpos.h"
|
#include "have_fpos.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -56,5 +61,11 @@ typedef struct {
|
|||||||
/*
|
/*
|
||||||
* external functions
|
* external functions
|
||||||
*/
|
*/
|
||||||
|
extern FILEIO * findid(FILEID id, int mode);
|
||||||
extern int fgetposid(FILEID id, FILEPOS *ptr);
|
extern int fgetposid(FILEID id, FILEPOS *ptr);
|
||||||
extern int fsetposid(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__ */
|
||||||
|
61
fposval.c
61
fposval.c
@@ -14,8 +14,8 @@
|
|||||||
*
|
*
|
||||||
* FILEPOS_BITS length in bits of the type FILEPOS
|
* FILEPOS_BITS length in bits of the type FILEPOS
|
||||||
* SWAP_HALF_IN_FILEPOS will copy/swap FILEPOS into an HALF array
|
* SWAP_HALF_IN_FILEPOS will copy/swap FILEPOS into an HALF array
|
||||||
* STSIZE_BITS length in bits of the st_size stat element
|
* OFF_T_BITS length in bits of the st_size stat element
|
||||||
* SWAP_HALF_IN_STSIZE will copy/swap st_size into an HALF array
|
* 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
|
* DEV_BITS length in bits of the st_dev stat element
|
||||||
* SWAP_HALF_IN_DEV will copy/swap st_dev into an HALF array
|
* SWAP_HALF_IN_DEV will copy/swap st_dev into an HALF array
|
||||||
* INODE_BITS length in bits of the st_ino stat element
|
* INODE_BITS length in bits of the st_ino stat element
|
||||||
@@ -55,6 +55,8 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include "have_fpos.h"
|
#include "have_fpos.h"
|
||||||
#include "endian_calc.h"
|
#include "endian_calc.h"
|
||||||
|
#include "have_offscl.h"
|
||||||
|
#include "have_posscl.h"
|
||||||
|
|
||||||
char *program; /* our name */
|
char *program; /* our name */
|
||||||
|
|
||||||
@@ -78,7 +80,7 @@ main(int argc, char **argv)
|
|||||||
fileposlen = sizeof(FILEPOS)*8;
|
fileposlen = sizeof(FILEPOS)*8;
|
||||||
printf("#undef FILEPOS_BITS\n");
|
printf("#undef FILEPOS_BITS\n");
|
||||||
printf("#define FILEPOS_BITS %d\n", fileposlen);
|
printf("#define FILEPOS_BITS %d\n", fileposlen);
|
||||||
#if BYTE_ORDER == BIG_ENDIAN
|
#if CALC_BYTE_ORDER == BIG_ENDIAN
|
||||||
/*
|
/*
|
||||||
* Big Endian
|
* Big Endian
|
||||||
*/
|
*/
|
||||||
@@ -93,49 +95,64 @@ main(int argc, char **argv)
|
|||||||
program, fileposlen);
|
program, fileposlen);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
#else /* BYTE_ORDER == BIG_ENDIAN */
|
#else /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||||
/*
|
/*
|
||||||
* Little 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
|
* 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",
|
printf("#define SWAP_HALF_IN_FILEPOS(dest, src)\t%s%d%s\n",
|
||||||
"memcpy((void *)(dest), (void *)(src), sizeof(",fileposlen,"))");
|
"memcpy((void *)(dest), (void *)(src), sizeof(",fileposlen,"))");
|
||||||
#endif /* BYTE_ORDER == BIG_ENDIAN */
|
#endif /* HAVE_FILEPOS_SCALAR */
|
||||||
|
#endif /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* print the stat file size information
|
* print the stat file size information
|
||||||
*/
|
*/
|
||||||
stsizelen = sizeof(buf.st_size)*8;
|
stsizelen = sizeof(buf.st_size)*8;
|
||||||
printf("#undef STSIZE_BITS\n");
|
printf("#undef OFF_T_BITS\n");
|
||||||
printf("#define STSIZE_BITS %d\n", stsizelen);
|
printf("#define OFF_T_BITS %d\n", stsizelen);
|
||||||
#if BYTE_ORDER == BIG_ENDIAN
|
#if CALC_BYTE_ORDER == BIG_ENDIAN
|
||||||
/*
|
/*
|
||||||
* Big Endian
|
* Big Endian
|
||||||
*/
|
*/
|
||||||
if (stsizelen == 64) {
|
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)");
|
"SWAP_HALF_IN_B64(dest, src)");
|
||||||
} else if (stsizelen == 32) {
|
} 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)");
|
"SWAP_HALF_IN_B32(dest, src)");
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s: unexpected st_size bit size: %d\n",
|
fprintf(stderr, "%s: unexpected st_size bit size: %d\n",
|
||||||
program, stsizelen);
|
program, stsizelen);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
#else /* BYTE_ORDER == BIG_ENDIAN */
|
#else /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||||
/*
|
/*
|
||||||
* Little Endian
|
* Little Endian
|
||||||
*
|
*
|
||||||
* Normally a "(*(dest) = *(src))" would do, but on some
|
* 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,"))");
|
"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');
|
putchar('\n');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -144,7 +161,7 @@ main(int argc, char **argv)
|
|||||||
devlen = sizeof(buf.st_dev)*8;
|
devlen = sizeof(buf.st_dev)*8;
|
||||||
printf("#undef DEV_BITS\n");
|
printf("#undef DEV_BITS\n");
|
||||||
printf("#define DEV_BITS %d\n", devlen);
|
printf("#define DEV_BITS %d\n", devlen);
|
||||||
#if BYTE_ORDER == BIG_ENDIAN
|
#if CALC_BYTE_ORDER == BIG_ENDIAN
|
||||||
/*
|
/*
|
||||||
* Big Endian
|
* Big Endian
|
||||||
*/
|
*/
|
||||||
@@ -162,7 +179,7 @@ main(int argc, char **argv)
|
|||||||
program, devlen);
|
program, devlen);
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
#else /* BYTE_ORDER == BIG_ENDIAN */
|
#else /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||||
/*
|
/*
|
||||||
* Little 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",
|
printf("#define SWAP_HALF_IN_DEV(dest, src)\t%s%d%s\n",
|
||||||
"memcpy((void *)(dest), (void *)(src), sizeof(",devlen,"))");
|
"memcpy((void *)(dest), (void *)(src), sizeof(",devlen,"))");
|
||||||
#endif /* BYTE_ORDER == BIG_ENDIAN */
|
#endif /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -180,7 +197,7 @@ main(int argc, char **argv)
|
|||||||
inodelen = sizeof(buf.st_ino)*8;
|
inodelen = sizeof(buf.st_ino)*8;
|
||||||
printf("#undef INODE_BITS\n");
|
printf("#undef INODE_BITS\n");
|
||||||
printf("#define INODE_BITS %d\n", inodelen);
|
printf("#define INODE_BITS %d\n", inodelen);
|
||||||
#if BYTE_ORDER == BIG_ENDIAN
|
#if CALC_BYTE_ORDER == BIG_ENDIAN
|
||||||
/*
|
/*
|
||||||
* Big Endian
|
* Big Endian
|
||||||
*/
|
*/
|
||||||
@@ -198,7 +215,7 @@ main(int argc, char **argv)
|
|||||||
program, inodelen);
|
program, inodelen);
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
#else /* BYTE_ORDER == BIG_ENDIAN */
|
#else /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||||
/*
|
/*
|
||||||
* Little Endian
|
* Little Endian
|
||||||
*
|
*
|
||||||
@@ -207,6 +224,6 @@ main(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
printf("#define SWAP_HALF_IN_INODE(dest, src)\t%s%d%s\n",
|
printf("#define SWAP_HALF_IN_INODE(dest, src)\t%s%d%s\n",
|
||||||
"memcpy((void *)(dest), (void *)(src), sizeof(",inodelen,"))");
|
"memcpy((void *)(dest), (void *)(src), sizeof(",inodelen,"))");
|
||||||
#endif /* BYTE_ORDER == BIG_ENDIAN */
|
#endif /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
||||||
exit(0);
|
exit(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,
|
* Permission is granted to use, distribute, or modify this source,
|
||||||
* provided that this copyright notice remains intact.
|
* provided that this copyright notice remains intact.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef FUNC_H
|
#if !defined(__FUNC_H__)
|
||||||
#define FUNC_H
|
#define __FUNC_H__
|
||||||
|
|
||||||
|
|
||||||
#include "calc.h"
|
#include "calc.h"
|
||||||
#include "label.h"
|
#include "label.h"
|
||||||
@@ -53,6 +54,9 @@ extern FUNC *findfunc(long index);
|
|||||||
extern char *namefunc(long index);
|
extern char *namefunc(long index);
|
||||||
extern BOOL evaluate(BOOL nestflag);
|
extern BOOL evaluate(BOOL nestflag);
|
||||||
extern long adduserfunc(char *name);
|
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 void beginfunc(char *name, BOOL newflag);
|
||||||
extern int builtinopcode(long index);
|
extern int builtinopcode(long index);
|
||||||
extern char *builtinname(long index);
|
extern char *builtinname(long index);
|
||||||
@@ -74,7 +78,8 @@ extern void clearopt(void);
|
|||||||
extern void updateoldvalue(FUNC *fp);
|
extern void updateoldvalue(FUNC *fp);
|
||||||
extern void calculate(FUNC *fp, int argcount);
|
extern void calculate(FUNC *fp, int argcount);
|
||||||
extern VALUE builtinfunc(long index, int argcount, VALUE *stck);
|
extern VALUE builtinfunc(long index, int argcount, VALUE *stck);
|
||||||
|
extern void freenumbers(FUNC *);
|
||||||
|
extern void freefunc(FUNC *);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* END CODE */
|
#endif /* !__FUNC_H__ */
|
||||||
|
110
hash.h
110
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
|
* Permission to use, copy, modify, and distribute this software and
|
||||||
* its documentation for any purpose and without fee is hereby granted,
|
* its documentation for any purpose and without fee is hereby granted,
|
||||||
@@ -21,30 +20,107 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* 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
|
* 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;
|
typedef struct hashstate HASH;
|
||||||
/* For ease in referencing */
|
struct hashstate {
|
||||||
#define h_shs h_union.hh_shs
|
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
|
* 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 SHS_HASH_TYPE 1
|
||||||
#define HASH_TYPE_MAX 0 /* must be number of XYZ_HASH_TYPE values */
|
#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__ */
|
||||||
|
@@ -40,6 +40,8 @@
|
|||||||
* chongo was here /\../\
|
* chongo was here /\../\
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
MAIN
|
MAIN
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
|
58
have_memmv.c
Normal file
58
have_memmv.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* have_memmv - Determine if we memmove()
|
||||||
|
*
|
||||||
|
* usage:
|
||||||
|
* have_newstr
|
||||||
|
*
|
||||||
|
* 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];
|
||||||
|
|
||||||
|
MAIN
|
||||||
|
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);
|
||||||
|
}
|
@@ -39,6 +39,8 @@
|
|||||||
* chongo was here /\../\
|
* chongo was here /\../\
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define MOVELEN 3
|
#define MOVELEN 3
|
||||||
|
|
||||||
char src[] = "chongo was here";
|
char src[] = "chongo was here";
|
||||||
|
83
have_offscl.c
Normal file
83
have_offscl.c
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
MAIN
|
||||||
|
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);
|
||||||
|
}
|
84
have_posscl.c
Normal file
84
have_posscl.c
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
MAIN
|
||||||
|
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);
|
||||||
|
}
|
@@ -36,6 +36,8 @@
|
|||||||
* chongo was here /\../\
|
* chongo was here /\../\
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#if !defined(HAVE_NO_UID_T)
|
#if !defined(HAVE_NO_UID_T)
|
||||||
#include "have_unistd.h"
|
#include "have_unistd.h"
|
||||||
#if defined(HAVE_UNISTD_H)
|
#if defined(HAVE_UNISTD_H)
|
||||||
|
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
|
CMP= cmp
|
||||||
CAT= cat
|
CAT= cat
|
||||||
|
|
||||||
# Standard help files
|
# Standard and Builtin help files
|
||||||
#
|
#
|
||||||
# The obj.file is special and is not listed here.
|
STD_HELP_FILES_1= intro overview help
|
||||||
#
|
STD_HELP_FILES_2= assoc
|
||||||
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
|
|
||||||
|
|
||||||
# These two lists are prodiced by the detaillist and missinglist rules
|
BLT_HELP_FILES_3= builtin
|
||||||
# when no WARNINGS are detected.
|
|
||||||
|
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 \
|
SPECIAL_HELP_7= obj.file
|
||||||
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 \
|
STD_HELP_FILES_8= operator statement
|
||||||
count cp csc csch ctime delete den det digit digits dp epsilon errno \
|
|
||||||
|
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 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 \
|
error eval exp fact factor fclose fcnt feof ferror fflush fgetc \
|
||||||
fgetfield fgetline fgets fgetstr fib files floor fopen forall fprintf \
|
fgetfield fgetline fgets fgetstr fib files floor fopen forall fprintf \
|
||||||
fputc fputs fputstr frac frem freopen fscan fscanf fseek fsize ftell \
|
fputc fputs fputstr frac free freeglobals freeredc freestatics frem \
|
||||||
gcd gcdrem getenv hash head highbit hmean hypot ilog ilog10 ilog2 im \
|
freopen fscan fscanf fseek fsize ftell gcd gcdrem gd getenv hash head \
|
||||||
insert int inverse iroot isassoc isatty isconfig iserror iseven \
|
highbit hmean hnrmod hypot ilog ilog10 ilog2 im insert int inverse \
|
||||||
isfile ishash isident isint islist ismat ismult isnull isnum isobj \
|
iroot isassoc isatty isblk isconfig isdefined iserror iseven isfile \
|
||||||
isodd isprime isqrt isrand israndom isreal isrel isset issimple issq \
|
ishash isident isint islist ismat ismult isnull isnum isobj isobjtype \
|
||||||
isstr istype jacobi join lcm lcmfact lfactor list ln lowbit ltol \
|
isodd isprime isptr isqrt isrand israndom isreal isrel issimple issq \
|
||||||
makelist matdim matfill matmax matmin matsum mattrans max meq min \
|
isstr istype jacobi join lcm lcmfact lfactor ln lowbit ltol makelist \
|
||||||
minv mmin mne mod modify near newerror nextcand nextprime norm null \
|
matdim matfill matmax matmin matsum mattrace mattrans max md5 memsize \
|
||||||
num ord param perm pfact pi pix places pmod polar poly pop power \
|
meq min minv mmin mne mod modify name near newerror nextcand \
|
||||||
prevcand prevprime printf prompt ptest push putenv quo quomod rand \
|
nextprime norm null num oldvalue ord param perm pfact pi pix places \
|
||||||
randbit randperm rcin rcmul rcout rcpow rcsq re rm remove reverse \
|
pmod polar poly pop popcnt power prevcand prevprime printf prompt \
|
||||||
rewind root round rsearch runtime scale scan scanf search sec sech \
|
protect ptest push putenv quo quomod rand randbit random randombit \
|
||||||
segment select sgn sin sinh size sizeof sort sqrt srand ssq str \
|
randperm rcin rcmul rcout rcpow rcsq re remove reverse rewind rm root \
|
||||||
strcat strerror strlen strpos strprintf strscan strscanf substr swap \
|
round rsearch runtime saveval scale scan scanf search sec sech \
|
||||||
system tail tan tanh time trunc xor
|
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.
|
DETAIL_CLONE= copy
|
||||||
#
|
|
||||||
BUILT_HELP_FILES= bindings altbind changes libcalc stdlib bugs errorcodes
|
|
||||||
|
|
||||||
# Singular files
|
# Singular files
|
||||||
#
|
#
|
||||||
@@ -94,12 +143,12 @@ SINGULAR_FILES= binding bug change errorcode type
|
|||||||
|
|
||||||
# These files are found (but not built) in the distribution
|
# 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 \
|
obj.file builtin.top builtin.end funclist.sed \
|
||||||
errorcodes.hdr errorcodes.sed
|
errorcodes.hdr errorcodes.sed
|
||||||
|
|
||||||
all: ${STD_HELP_FILES} obj.file ${BUILT_HELP_FILES} full \
|
all: ${FULL_HELP_FILES} full ${DETAIL_HELP} ${DETAIL_CLONE} \
|
||||||
${DETAIL_HELP} ${SINGULAR_FILES} builtin .all
|
${SINGULAR_FILES} calc .all
|
||||||
|
|
||||||
# used by the upper level Makefile to determine of we have done 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
|
touch .all
|
||||||
|
|
||||||
bindings: ../lib/bindings
|
bindings: ../lib/bindings
|
||||||
rm -f bindings
|
rm -f $@
|
||||||
cp ../lib/bindings bindings
|
cp ../lib/bindings $@
|
||||||
chmod 0444 bindings
|
chmod 0444 $@
|
||||||
-@if [ -z "${Q}" ]; then \
|
-@if [ -z "${Q}" ]; then \
|
||||||
echo ''; \
|
echo ''; \
|
||||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||||
@@ -123,9 +172,9 @@ bindings: ../lib/bindings
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
altbind: ../lib/altbind
|
altbind: ../lib/altbind
|
||||||
rm -f altbind
|
rm -f $@
|
||||||
cp ../lib/altbind altbind
|
cp ../lib/altbind $@
|
||||||
chmod 0444 altbind
|
chmod 0444 $@
|
||||||
-@if [ -z "${Q}" ]; then \
|
-@if [ -z "${Q}" ]; then \
|
||||||
echo ''; \
|
echo ''; \
|
||||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||||
@@ -135,9 +184,9 @@ altbind: ../lib/altbind
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
stdlib: ../lib/README
|
stdlib: ../lib/README
|
||||||
rm -f stdlib
|
rm -f $@
|
||||||
cp ../lib/README stdlib
|
cp ../lib/README $@
|
||||||
chmod 0444 stdlib
|
chmod 0444 $@
|
||||||
-@if [ -z "${Q}" ]; then \
|
-@if [ -z "${Q}" ]; then \
|
||||||
echo ''; \
|
echo ''; \
|
||||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||||
@@ -147,9 +196,9 @@ stdlib: ../lib/README
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
changes: ../CHANGES
|
changes: ../CHANGES
|
||||||
rm -f changes
|
rm -f $@
|
||||||
cp ../CHANGES changes
|
cp ../CHANGES $@
|
||||||
chmod 0444 changes
|
chmod 0444 $@
|
||||||
-@if [ -z "${Q}" ]; then \
|
-@if [ -z "${Q}" ]; then \
|
||||||
echo ''; \
|
echo ''; \
|
||||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||||
@@ -159,9 +208,9 @@ changes: ../CHANGES
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
libcalc: ../LIBRARY
|
libcalc: ../LIBRARY
|
||||||
rm -f libcalc
|
rm -f $@
|
||||||
${SED} -e 's:$${LIBDIR}:${LIBDIR}:g' < ../LIBRARY > libcalc
|
${SED} -e 's:$${LIBDIR}:${LIBDIR}:g' < ../LIBRARY > $@
|
||||||
chmod 0444 libcalc
|
chmod 0444 $@
|
||||||
-@if [ -z "${Q}" ]; then \
|
-@if [ -z "${Q}" ]; then \
|
||||||
echo ''; \
|
echo ''; \
|
||||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||||
@@ -171,9 +220,9 @@ libcalc: ../LIBRARY
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
bugs: ../BUGS
|
bugs: ../BUGS
|
||||||
rm -f bugs
|
rm -f $@
|
||||||
cp ../BUGS bugs
|
cp ../BUGS $@
|
||||||
chmod 0444 bugs
|
chmod 0444 $@
|
||||||
-@if [ -z "${Q}" ]; then \
|
-@if [ -z "${Q}" ]; then \
|
||||||
echo ''; \
|
echo ''; \
|
||||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||||
@@ -183,10 +232,10 @@ bugs: ../BUGS
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
errorcodes: ../calcerr.h errorcodes.hdr errorcodes.sed
|
errorcodes: ../calcerr.h errorcodes.hdr errorcodes.sed
|
||||||
rm -f errorcodes
|
rm -f $@
|
||||||
${CAT} errorcodes.hdr > errorcodes
|
${CAT} errorcodes.hdr > $@
|
||||||
${SED} -n -f errorcodes.sed < ../calcerr.h >> errorcodes
|
${SED} -n -f errorcodes.sed < ../calcerr.h >> $@
|
||||||
chmod 0444 errorcodes
|
chmod 0444 $@
|
||||||
-@if [ -z "${Q}" ]; then \
|
-@if [ -z "${Q}" ]; then \
|
||||||
echo ''; \
|
echo ''; \
|
||||||
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
echo '=-=-= skipping the cat of help/$@ =-=-='; \
|
||||||
@@ -195,11 +244,58 @@ errorcodes: ../calcerr.h errorcodes.hdr errorcodes.sed
|
|||||||
true; \
|
true; \
|
||||||
fi
|
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}echo "forming full"
|
||||||
-${Q}rm -f full
|
-${Q}rm -f $@
|
||||||
-${Q}for i in ${STD_HELP_FILES1} obj.file ${STD_HELP_FILES2} \
|
-${Q}for i in ${FULL_HELP_FILES}; do \
|
||||||
${BUILT_HELP_FILES} ${STD_HELP_FILES3}; do \
|
|
||||||
if [ Xintro != X"$$i" ]; then \
|
if [ Xintro != X"$$i" ]; then \
|
||||||
echo ""; \
|
echo ""; \
|
||||||
else \
|
else \
|
||||||
@@ -215,7 +311,7 @@ full: ${STD_HELP_FILES} ${BUILT_HELP_FILES} ${MAKE_FILE}
|
|||||||
echo "*************"; \
|
echo "*************"; \
|
||||||
echo ""; \
|
echo ""; \
|
||||||
cat $$i; \
|
cat $$i; \
|
||||||
done > full
|
done > $@
|
||||||
${Q}echo "full formed"
|
${Q}echo "full formed"
|
||||||
-@if [ -z "${Q}" ]; then \
|
-@if [ -z "${Q}" ]; then \
|
||||||
echo ''; \
|
echo ''; \
|
||||||
@@ -302,8 +398,8 @@ distlist: ${DISTLIST}
|
|||||||
|
|
||||||
# The bsdi distribution has generated files as well as distributed files.
|
# The bsdi distribution has generated files as well as distributed files.
|
||||||
#
|
#
|
||||||
bsdilist: ${DISTLIST} ${BUILT_HELP_FILES}
|
bsdilist: ${DISTLIST} ${BLT_HELP_FILES}
|
||||||
${Q}for i in ${DISTLIST} ${BUILT_HELP_FILES}; do \
|
${Q}for i in ${DISTLIST} ${BLT_HELP_FILES}; do \
|
||||||
echo calc/help/$$i; \
|
echo calc/help/$$i; \
|
||||||
done | ${SORT}
|
done | ${SORT}
|
||||||
|
|
||||||
@@ -333,8 +429,9 @@ clean:
|
|||||||
rm -f obj mkbuiltin funclist.c funclist.o funclist
|
rm -f obj mkbuiltin funclist.c funclist.o funclist
|
||||||
|
|
||||||
clobber:
|
clobber:
|
||||||
rm -f ${BUILT_HELP_FILES} full builtin .all
|
rm -f ${BLT_HELP_FILES} full .all calc
|
||||||
rm -f obj mkbuiltin funclist.c funclist.o funclist ${SINGULAR_FILES}
|
rm -f obj mkbuiltin funclist.c funclist.o funclist
|
||||||
|
rm -f ${SINGULAR_FILES} ${DETAIL_CLONE}
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
-${Q}if [ ! -d ${TOPDIR} ]; then \
|
-${Q}if [ ! -d ${TOPDIR} ]; then \
|
||||||
@@ -355,8 +452,8 @@ install: all
|
|||||||
else \
|
else \
|
||||||
true; \
|
true; \
|
||||||
fi
|
fi
|
||||||
${Q}for i in ${STD_HELP_FILES} ${BUILT_HELP_FILES} builtin \
|
${Q}for i in ${STD_HELP_FILES} ${BLT_HELP_FILES} builtin \
|
||||||
full ${DETAIL_HELP} ${SINGULAR_FILES} ${SYMBOL_HELP}; do \
|
full ${DETAIL_HELP} ${SINGULAR_FILES}; do \
|
||||||
echo rm -f ${HELPDIR}/$$i; \
|
echo rm -f ${HELPDIR}/$$i; \
|
||||||
rm -f ${HELPDIR}/$$i; \
|
rm -f ${HELPDIR}/$$i; \
|
||||||
echo cp $$i ${HELPDIR}; \
|
echo cp $$i ${HELPDIR}; \
|
||||||
@@ -367,3 +464,5 @@ install: all
|
|||||||
rm -f ${HELPDIR}/obj
|
rm -f ${HELPDIR}/obj
|
||||||
cp obj.file ${HELPDIR}/obj
|
cp obj.file ${HELPDIR}/obj
|
||||||
chmod 0444 ${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,
|
eps ignored if x is real, nonzero real for complex x,
|
||||||
defaults to epsilon().
|
defaults to epsilon().
|
||||||
|
|
||||||
return real
|
return non-negative real
|
||||||
|
|
||||||
DESCRIPTION
|
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
|
For complex x with zero real part, returns the absolute value of im(x).
|
||||||
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 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
|
EXAMPLE
|
||||||
> print abs(3.4), abs(-3.4)
|
> print abs(3.4), abs(-3.4)
|
||||||
@@ -35,7 +39,7 @@ LIMITS
|
|||||||
none
|
none
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
none
|
NUMBER *qqabs(NUMBER *x)
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
cmp, epsilon, hypot, norm, near, obj
|
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.
|
'w' or bit 1 for writing, 'x' or bit 0 for execution.
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
|
The system error-numbers and messages may differ for different
|
||||||
|
implementations
|
||||||
|
|
||||||
> !rm -f junk
|
> !rm -f junk
|
||||||
> access("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")
|
> f = fopen("junk", "w")
|
||||||
> access("junk")
|
> access("junk")
|
||||||
> fputs(f, "Now is the time");
|
> fputs(f, "Alpha")
|
||||||
> freopen(f, "r");
|
> fclose(f)
|
||||||
> !chmod u-w junk
|
> !chmod u-w junk
|
||||||
> fgets(f)
|
|
||||||
"Now is the time"
|
|
||||||
> access("junk", "w")
|
> access("junk", "w")
|
||||||
Error 10013 XXX
|
System error 13
|
||||||
> freopen(f, "w")
|
> strerror(.)
|
||||||
Error 10013 XXX
|
"Permission denied"
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
none - XXX - is this correct?
|
There may be implementation-dependent limits inherited from the
|
||||||
|
system call "access" used by this function.
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
none - XXX - is this correct?
|
none
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
errno, fclose, feof, ferror, fflush, fgetc, fgetline, fgets, files, fopen,
|
fopen, fclose, isfile, files
|
||||||
fprintf, fputc, fputs, fseek, fsize, ftell, isfile, printf, prompt
|
|
||||||
|
@@ -21,9 +21,7 @@ EXAMPLE
|
|||||||
1.0472 1.0471975512 1.047197551196598 1.04719755119659774615
|
1.0472 1.0471975512 1.047197551196598 1.04719755119659774615
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
abs(x) <= 1
|
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qacos(NUMBER *x, NUMBER *eps)
|
NUMBER *qacos(NUMBER *x, NUMBER *eps)
|
||||||
|
11
help/acosh
11
help/acosh
@@ -11,19 +11,20 @@ TYPES
|
|||||||
return nonnegative real
|
return nonnegative real
|
||||||
|
|
||||||
DESCRIPTION
|
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.
|
absolute value than .75 * eps.
|
||||||
|
|
||||||
acosh(x) = ln(x + sqrt(x^2 - 1)) is the nonnegative real number v
|
acosh(x) is the nonnegative real number v for which cosh(v) = x.
|
||||||
for which cosh(v) = x.
|
It is given by
|
||||||
|
|
||||||
|
acosh(x) = ln(x + sqrt(x^2 - 1))
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
> print acosh(2, 1e-5), acosh(2, 1e-10), acosh(2, 1e-15), acosh(2, 1e-20)
|
> 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
|
1.31696 1.3169578969 1.316957896924817 1.31695789692481670862
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qacosh(NUMBER *x, NUMBER *eps)
|
NUMBER *qacosh(NUMBER *x, NUMBER *eps)
|
||||||
|
@@ -21,8 +21,7 @@ EXAMPLE
|
|||||||
.46365 .463647609 .463647609000806 .46364760900080611621
|
.46365 .463647609 .463647609000806 .46364760900080611621
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qacot(NUMBER *x, NUMBER *eps)
|
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
|
Returns the acoth of x to a multiple of eps with error less in
|
||||||
absolute value than .75 * eps.
|
absolute value than .75 * eps.
|
||||||
|
|
||||||
acoth(x) = ln((x + 1)/(x - 1))/2 is the real number v for which
|
acoth(x) is the real number v for which coth(v) = x.
|
||||||
coth(v) = x.
|
It is given by
|
||||||
|
acoth(x) = ln((x + 1)/(x - 1))/2
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
> print acoth(2, 1e-5), acoth(2, 1e-10), acoth(2, 1e-15), acoth(2, 1e-20)
|
> print acoth(2, 1e-5), acoth(2, 1e-10), acoth(2, 1e-15), acoth(2, 1e-20)
|
||||||
.54931 .5493061443 .549306144334055 .5493061443340548457
|
.54931 .5493061443 .549306144334055 .5493061443340548457
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
abs(x) > 1
|
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qacoth(NUMBER *x, NUMBER *eps)
|
NUMBER *qacoth(NUMBER *x, NUMBER *eps)
|
||||||
|
@@ -21,9 +21,7 @@ EXAMPLE
|
|||||||
.5236 .5235987756 .523598775598299 .52359877559829887308
|
.5236 .5235987756 .523598775598299 .52359877559829887308
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
abs(x) >= 1
|
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qacsc(NUMBER *x, NUMBER *eps)
|
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
|
Returns the acsch of x to a multiple of eps with error less in
|
||||||
absolute value than .75 * eps.
|
absolute value than .75 * eps.
|
||||||
|
|
||||||
acsch(x) = ln((1 + sqrt(1 + x^2))/x) is the real number v for
|
acsch(x) is the real number v for which csch(v) = x. It is given by
|
||||||
which csch(v) = x.
|
|
||||||
|
acsch(x) = ln((1 + sqrt(1 + x^2))/x)
|
||||||
|
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
> print acsch(2, 1e-5), acsch(2, 1e-10), acsch(2, 1e-15), acsch(2, 1e-20)
|
> print acsch(2, 1e-5), acsch(2, 1e-10), acsch(2, 1e-15), acsch(2, 1e-20)
|
||||||
.48121 .4812118251 .481211825059603 .4812118250596034475
|
.48121 .4812118251 .481211825059603 .4812118250596034475
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
x != 0
|
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qacsch(NUMBER *x, NUMBER *eps)
|
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.
|
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.
|
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
|
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
|
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 = 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
|
z = 6 round towards or from zero according as y is positive or
|
||||||
negative, sgn(r) = sgn(x/y)
|
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,
|
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).
|
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
|
PROPERTIES
|
||||||
If appr(x,y,z) != x, then abs(x - appr(x,y,z)) < abs(y).
|
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)
|
> print appr(-.44,-.1,15),appr(.44,-.1,15),appr(5.7,-1,15),appr(-5.7,-1,15)
|
||||||
-.4 .5 5 -6
|
-.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
|
LIMITS
|
||||||
none
|
none
|
||||||
|
|
||||||
|
@@ -22,4 +22,10 @@ Where to get the the latest versions of calc
|
|||||||
where "address" is your EMail address and "your_full_name"
|
where "address" is your EMail address and "your_full_name"
|
||||||
is your full name.
|
is your full name.
|
||||||
|
|
||||||
Landon Curt Noll <chongo@toad.com> /\oo/\
|
See:
|
||||||
|
|
||||||
|
http://prime.corp.sgi.com/csp/ioccc/noll/noll.html#calc
|
||||||
|
|
||||||
|
for details.
|
||||||
|
|
||||||
|
Landon Curt Noll <chongo@toad.com> /\oo/\
|
||||||
|
2
help/arg
2
help/arg
@@ -13,7 +13,7 @@ TYPES
|
|||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Returns the argument of x to the nearest or next to nearest multiple of
|
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),
|
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
|
EXAMPLE
|
||||||
> print arg(2), arg(2+3i, 1e-5), arg(2+3i, 1e-10), arg(2+3i, 1e-20)
|
> 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
|
1.0472 1.0471975512 1.047197551196598 1.04719755119659774615
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
abs(x) >= 1
|
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qasec(NUMBER *x, NUMBER *eps)
|
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
|
Returns the asech of x to a multiple of eps with error less in
|
||||||
absolute value than .75 * eps.
|
absolute value than .75 * eps.
|
||||||
|
|
||||||
asech(x) = ln((1 + sqrt(1 - x^2))/x) is the real number v for which
|
asech(x) is the real number v for which sech(v) = x. It is given by
|
||||||
sech(v) = x.
|
|
||||||
|
asech(x) = ln((1 + sqrt(1 - x^2))/x)
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
> print asech(.5,1e-5), asech(.5,1e-10), asech(.5,1e-15), asech(.5,1e-20)
|
> 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
|
1.31696 1.3169578969 1.316957896924817 1.31695789692481670862
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
0 < x <= 1
|
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qasech(NUMBER *x, NUMBER *eps)
|
NUMBER *qasech(NUMBER *x, NUMBER *eps)
|
||||||
|
@@ -21,9 +21,7 @@ EXAMPLE
|
|||||||
.5236 .5235987756 .523598775598299 .52359877559829887308
|
.5236 .5235987756 .523598775598299 .52359877559829887308
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
abs(x) <= 1
|
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qasin(NUMBER *q, NUMBER *epsilon)
|
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
|
Returns the asinh of x to a multiple of eps with error less in
|
||||||
absolute value than .75 * eps.
|
absolute value than .75 * eps.
|
||||||
|
|
||||||
asinh(x) = ln(x + sqrt(1 + x^2)) is the real number v for which
|
asinh(x) is the real number v for which sinh(v) = x. It is given by
|
||||||
sinh(v) = x.
|
|
||||||
|
asinh(x) = ln(x + sqrt(1 + x^2))
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
> print asinh(2, 1e-5), asinh(2, 1e-10), asinh(2, 1e-15), asinh(2, 1e-20)
|
> 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
|
1.44363 1.4436354752 1.44363547517881 1.44363547517881034249
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qasinh(NUMBER *x, NUMBER *eps)
|
NUMBER *qasinh(NUMBER *x, NUMBER *eps)
|
||||||
|
97
help/assign
97
help/assign
@@ -3,22 +3,111 @@ NAME
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
a = b
|
a = b
|
||||||
|
a = {e_1, e_2, ...[ { ... } ] }
|
||||||
|
|
||||||
TYPES
|
TYPES
|
||||||
a lvalue
|
a lvalue, current value a structure in { } case
|
||||||
b expression
|
|
||||||
|
|
||||||
return lvalue
|
b expression
|
||||||
|
|
||||||
|
e_0, e_1, ... expressions, blanks, or initializer lists
|
||||||
|
|
||||||
|
|
||||||
|
return lvalue (a)
|
||||||
|
|
||||||
DESCRIPTION
|
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 = 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
|
EXAMPLE
|
||||||
> b = 3+1
|
> b = 3+1
|
||||||
> a = b
|
> a = b
|
||||||
> print a, b
|
> print a, b
|
||||||
4 4
|
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
|
LIMITS
|
||||||
none
|
none
|
||||||
|
|
||||||
@@ -26,4 +115,4 @@ LIBRARY
|
|||||||
none
|
none
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
XXX - fill in
|
swap, quomod
|
||||||
|
57
help/assoc
57
help/assoc
@@ -8,38 +8,34 @@ TYPES
|
|||||||
return association
|
return association
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
This functions returns an empty association array.
|
This function returns an empty association array.
|
||||||
|
|
||||||
Associations are special values that act like matrices, except
|
After A = assoc(), elements can be added to the association by
|
||||||
that they are more general (and slower) than normal matrices.
|
assignments of the forms
|
||||||
Unlike matrices, associations can be indexed by arbitrary values.
|
|
||||||
For example, if 'val' was an association, you could do the following:
|
|
||||||
|
|
||||||
val['hello'] = 11;
|
A[a_1] = v_1
|
||||||
val[4.5] = val['hello'];
|
A[a_1, a_2] = v_2
|
||||||
print val[9/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
|
After the above assignments, so long as no new values have been
|
||||||
arguments, and simply returns an empty association. You can then
|
assigned to A[a_i], etc., the expressions A[a_1], A[a_1, a_2], etc.
|
||||||
insert elements into the association by indexing the returned value
|
will return the values v_1, v_2, ...
|
||||||
as shown above.
|
|
||||||
|
|
||||||
Associations are multi-dimensional. You can index them using one to
|
Until A[a_1], A[a_1, a_2], ... are defined as described above, these
|
||||||
four dimensions as desired, and the elements with different numbers
|
expressions return the null value.
|
||||||
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.
|
|
||||||
|
|
||||||
When references are made to undefined elements of an association,
|
Thus associations act like matrices except that different elements
|
||||||
a null value is simply returned. Therefore no bounds errors can
|
may have different numbers (between 1 and 4 inclusive) of indices,
|
||||||
occur when indexing an association. Assignments of a null value
|
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
|
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
|
a later reference to that element will return the null value as if
|
||||||
the element was undefined. Elements with null values are implicitly
|
the element is undefined.
|
||||||
created on certain other operations which require an address to be
|
|
||||||
taken, such as the += operator and using & in a function call.
|
|
||||||
|
|
||||||
The elements of an association are stored in a hash table for
|
The elements of an association are stored in a hash table for
|
||||||
quick access. The index values are hashed to select the correct
|
quick access. The index values are hashed to select the correct
|
||||||
@@ -65,9 +61,18 @@ DESCRIPTION
|
|||||||
and are illegal.
|
and are illegal.
|
||||||
|
|
||||||
EXAMPLE
|
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
|
LIMITS
|
||||||
none
|
none
|
||||||
|
@@ -21,8 +21,7 @@ EXAMPLE
|
|||||||
1.10715 1.1071487178 1.107148717794091 1.10714871779409050302
|
1.10715 1.1071487178 1.107148717794091 1.10714871779409050302
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qatan(NUMBER *x, NUMBER *eps)
|
NUMBER *qatan(NUMBER *x, NUMBER *eps)
|
||||||
|
21
help/atan2
21
help/atan2
@@ -2,32 +2,33 @@ NAME
|
|||||||
atan2 - angle to point
|
atan2 - angle to point
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
atan2(y, x, [,acc])
|
atan2(y, x, [,eps])
|
||||||
|
|
||||||
TYPES
|
TYPES
|
||||||
y real
|
y real
|
||||||
x real
|
x real
|
||||||
acc real
|
eps nonzero real, defaults to epsilon()
|
||||||
|
|
||||||
return real
|
return real
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Return the angle which is determined by the point (x,y). This
|
If x and y are not both zero, atan2(y, x, eps) returns, as a multiple of
|
||||||
function computes the arctangent of y/x in the range [-pi, pi].
|
eps with error less than abs(eps), the angle t such that
|
||||||
The value acc specifies the accuracy of the result. By default, acc
|
-pi < t <= pi and x = r * cos(t), y = r * sin(t), where
|
||||||
is epsilon().
|
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
|
To conform to the 4.3BSD ANSI/IEEE 754-1985 math lib, atan2(0,0)
|
||||||
defined to return 0.
|
returns 0.
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
> print atan2(0,0), atan2(1,sqrt(3)), atan2(17,53,1e-100)
|
> print atan2(0,0), atan2(1,sqrt(3)), atan2(17,53,1e-100)
|
||||||
0 ~.52359877559829887307 ~.31038740713235146535
|
0 ~.52359877559829887307 ~.31038740713235146535
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
acc > 0
|
none
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qatan2(NUMBER *y, *x, *acc)
|
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
|
Returns the atanh of x to a multiple of eps with error less in
|
||||||
absolute value than .75 * eps.
|
absolute value than .75 * eps.
|
||||||
|
|
||||||
atanh(x) = ln((1 + x)/(1 - x))/2 is the real number v for whichi
|
atanh(x) is the real number v for which tanh(v) = x. It is given by
|
||||||
tanh(v) = x.
|
|
||||||
|
atanh(x) = ln((1 + x)/(1 - x))/2
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
> print atanh(.5,1e-5), atanh(.5,1e-10), atanh(.5,1e-15), atanh(.5,1e-20)
|
> print atanh(.5,1e-5), atanh(.5,1e-10), atanh(.5,1e-15), atanh(.5,1e-20)
|
||||||
.54931 .5493061443 .549306144334055 .5493061443340548457
|
.54931 .5493061443 .549306144334055 .5493061443340548457
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qatanh(NUMBER *x, NUMBER *eps)
|
NUMBER *qatanh(NUMBER *x, NUMBER *eps)
|
||||||
|
@@ -11,7 +11,7 @@ TYPES
|
|||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
The base function allows one to specify how numbers should be
|
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
|
config("mode") interface. With no args, base() will return the
|
||||||
current mode. With 1 arg, base(val) will set the mode according to
|
current mode. With 1 arg, base(val) will set the mode according to
|
||||||
the arg and return the previous mode.
|
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
|
58
help/blkfree
Normal file
58
help/blkfree
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
NAME
|
||||||
|
blkfree - free memory allocated to named block
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
blkfree(val)
|
||||||
|
|
||||||
|
TYPES
|
||||||
|
val named block, string, or integer
|
||||||
|
|
||||||
|
return null value
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
If val is a named block, or the name of a named block, or the
|
||||||
|
identifying index for a named block, blkfree(val) frees the
|
||||||
|
memory block allocated to this named block. The block remains
|
||||||
|
in existence with the same name, identifying index, and chunksize,
|
||||||
|
but its size and maxsize becomes zero and the pointer for the start
|
||||||
|
of its data block null.
|
||||||
|
|
||||||
|
A new block of memory may be allocated to a freed block B by
|
||||||
|
blk(B [, len, chunk]), len defaulting to zero and chunk to the
|
||||||
|
chunksize when the block was freed.
|
||||||
|
|
||||||
|
EXAMPLE
|
||||||
|
|
||||||
|
> B1 = blk("foo")
|
||||||
|
> B2 = blk("Second block")
|
||||||
|
show blocks
|
||||||
|
id name
|
||||||
|
---- -----
|
||||||
|
0 foo
|
||||||
|
1 Second block
|
||||||
|
|
||||||
|
> blkfree(B1)
|
||||||
|
> show blocks
|
||||||
|
id name
|
||||||
|
---- -----
|
||||||
|
1 Second block
|
||||||
|
|
||||||
|
> B1
|
||||||
|
block 0: foo
|
||||||
|
chunksize = 256, maxsize = 0, datalen = 0
|
||||||
|
NULL
|
||||||
|
|
||||||
|
> blk(B1); B[7] = 5
|
||||||
|
> B1
|
||||||
|
block 0: foo
|
||||||
|
chunksize = 256, maxsize = 256, datalen = 8
|
||||||
|
0000000000000005
|
||||||
|
|
||||||
|
LIMITS
|
||||||
|
none
|
||||||
|
|
||||||
|
LIBRARY
|
||||||
|
none
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
blk, blocks
|
43
help/blocks
Normal file
43
help/blocks
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
NAME
|
||||||
|
blocks - return a named file or number of unfreed named blocks
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
blocks([id])
|
||||||
|
|
||||||
|
TYPES
|
||||||
|
id non-negative integer
|
||||||
|
|
||||||
|
return named block or null value
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
With no argument blocks() returns the number of blocks that have
|
||||||
|
been created but not freed by the blkfree function.
|
||||||
|
|
||||||
|
With argument id less than the number of named blocks that have been
|
||||||
|
created, blocks(id) returns the named block with identifying index id.
|
||||||
|
These indices 0, 1, 2, ... are assigned to named blocks in the order
|
||||||
|
of their creation.
|
||||||
|
|
||||||
|
EXAMPLE
|
||||||
|
|
||||||
|
> A = blk("alpha")
|
||||||
|
> B = blk("beta") = {1,2,3}
|
||||||
|
> blocks()
|
||||||
|
2
|
||||||
|
> blocks(1)
|
||||||
|
block 1: beta
|
||||||
|
chunksize = 256, maxsize = 256, datalen = 3
|
||||||
|
010203
|
||||||
|
> blocks(2)
|
||||||
|
Error 10211
|
||||||
|
> strerror()
|
||||||
|
"Non-allocated index number for blocks"
|
||||||
|
|
||||||
|
LIMITS
|
||||||
|
none
|
||||||
|
|
||||||
|
LIBRARY
|
||||||
|
none
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
blk, blkfree
|
20
help/btrunc
20
help/btrunc
@@ -2,19 +2,24 @@ NAME
|
|||||||
btrunc - truncate a value to a number of binary places
|
btrunc - truncate a value to a number of binary places
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
btrunc(x [,j])
|
btrunc(x [,plcs])
|
||||||
|
|
||||||
TYPES
|
TYPES
|
||||||
x real
|
x real
|
||||||
j int
|
plcs integer, defaults to zero
|
||||||
|
|
||||||
return real
|
return real
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Truncate x to j binary places. If j is omitted, 0 places is assumed.
|
Truncate x to plcs binary places, rounding if necessary towards zero,
|
||||||
Specifying zero places makes the result identical to int().
|
i.e. btrunc(x, plcs) is a multiple of 2^-plcs and the remainder
|
||||||
|
x - btrunc(x, plcs) is either zero or has the same sign as x and
|
||||||
|
absolute value less than 2^-plcs. Here plcs may be positive, zero or
|
||||||
|
negative.
|
||||||
|
|
||||||
Truncation of a non-integer prodcues values nearer to zero.
|
Except that it is defined only for real x, btrunc(x, plcs) is equivalent
|
||||||
|
to bround(x, plcs, 2). btrunc(x,0) and btrunc(x) are equivalent to
|
||||||
|
int(x).
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
> print btrunc(pi()), btrunc(pi(), 10)
|
> print btrunc(pi()), btrunc(pi(), 10)
|
||||||
@@ -26,8 +31,11 @@ EXAMPLE
|
|||||||
> print btrunc(-3.3), btrunc(-3.7), btrunc(-3.3, 2), btrunc(-3.7, 2)
|
> print btrunc(-3.3), btrunc(-3.7), btrunc(-3.3, 2), btrunc(-3.7, 2)
|
||||||
-3 -3 -3.25 -3.5
|
-3 -3 -3.25 -3.5
|
||||||
|
|
||||||
|
> print btrunc(55.123, -4), btrunc(-55.123, -4)
|
||||||
|
48 -48
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
0 <= j < 2^31
|
abs(j) < 2^31
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qbtrunc(NUMBER *x, *j)
|
NUMBER *qbtrunc(NUMBER *x, *j)
|
||||||
|
@@ -35,10 +35,10 @@
|
|||||||
the user. For example, x=eval(prompt("Number: ")) sets x to the
|
the user. For example, x=eval(prompt("Number: ")) sets x to the
|
||||||
value input by the user.
|
value input by the user.
|
||||||
|
|
||||||
The digit and isset functions return individual digits of a number,
|
The digit and bit functions return individual digits of a number,
|
||||||
either in base 10 or in base 2, where the lowest digit of a number
|
either in base 10 or in base 2, where the lowest digit of a number
|
||||||
is at digit position 0. For example, digit(5678, 3) is 5, and
|
is at digit position 0. For example, digit(5678, 3) is 5, and
|
||||||
isset(0b1000100, 2) is 1. Negative digit positions indicate places
|
bit(0b1000100, 2) is 1. Negative digit positions indicate places
|
||||||
to the right of the decimal or binary point, so that for example,
|
to the right of the decimal or binary point, so that for example,
|
||||||
digit(3.456, -1) is 4.
|
digit(3.456, -1) is 4.
|
||||||
|
|
||||||
|
@@ -13,8 +13,11 @@ DESCRIPTION
|
|||||||
this function will return an empty string.
|
this function will return an empty string.
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
> cmdbuf("")
|
% calc "print cmdbuf(); a = 3; print a^2;"
|
||||||
""
|
print cmdbuf(); a = 3; print a^2;
|
||||||
|
|
||||||
|
9
|
||||||
|
%
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
none
|
none
|
||||||
|
105
help/cmp
105
help/cmp
@@ -1,71 +1,95 @@
|
|||||||
NAME
|
NAME
|
||||||
cmp - compare two values
|
cmp - compare two values of certain simple or object types
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
cmp(x, y)
|
cmp(x, y)
|
||||||
|
|
||||||
TYPES
|
TYPES
|
||||||
If x is an object of type xx or x is not an object and y is an object
|
If x is an object of type xx, or x is not an object and y is an object
|
||||||
of type xx, the funcion xx_cmp has to have been defined; any
|
of type xx, the function xx_rel has to have been defined; any
|
||||||
further conditions on x and y, and the type of the returned
|
further conditions on x and y, and the type of the returned
|
||||||
value depends on the definition of xx_cmp.
|
value depends on the definition of xx_rel.
|
||||||
|
|
||||||
For non-object x and y:
|
For non-object x and y:
|
||||||
|
|
||||||
x number or string
|
x any
|
||||||
y same as x
|
y any
|
||||||
|
|
||||||
return -1, 0, 1 (real & string)
|
return if x and y are both real: -1, 0, or 1
|
||||||
-1, 0, 1, -1+1i, 1i, 1+1i, -1-1i, -1i or 1-1i (complex)
|
if x and y are both numbers but not both real:
|
||||||
|
-1, 0, 1, -1+1i, 1i, 1+1i, -1-1i, -1i, or 1-1i
|
||||||
|
if x and y are both strings: -1, 0, or 1
|
||||||
|
all other cases: the null value
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Compare two values and return a value based on their relationship.
|
|
||||||
Comparison by type is indicated below. Where more than one test is
|
|
||||||
indicated, tests are performed in the order listed. If the test is
|
|
||||||
inconclusive, the next test is performed. If all tests are
|
|
||||||
inconclusive, the values are considered equivalent.
|
|
||||||
|
|
||||||
real (returns -1, 0, or 1)
|
x and y both real: cmp(x, y) = sgn(x - y), i.e. -1, 0, or 1
|
||||||
the greater number is greater
|
according as x < y, x == y, or x > y
|
||||||
|
|
||||||
complex (returns -1, 0, 1, -1+1i, 1i, 1+1i, -1-1i, -1i or 1-1i)
|
x and y both numbers, at least one being complex:
|
||||||
sgn(re(x) - re(y)) + sgn(im(x) - im(y)) * 1i
|
cmp(x,y) = sgn(re(x) - re(y)) + sgn(im(x) - im(y)) * 1i
|
||||||
|
|
||||||
string (returns -1, 0, or 1)
|
x and y both strings: successive characters are compared until either
|
||||||
the string with the greater first different character is greater
|
different characters are encountered or at least one string is
|
||||||
the longer string is greater
|
completed. If the comparison ends because of different characters,
|
||||||
|
cmp(x,y) = 1 or -1 according as the greater character is in x or y.
|
||||||
|
If all characters compared in both strings are equal, then
|
||||||
|
cmp(x,y) = -1, 0 or 1 according as the length of x is less than,
|
||||||
|
equal to, or greater than the length of y. (This comparison
|
||||||
|
is performed via the strcmp() libc function.)
|
||||||
|
|
||||||
object (depends on xx_cmp)
|
objects: comparisons of objects are usually intended for some total or
|
||||||
the greater object as defined by xx_cmp is greater
|
partial ordering and appropriate definitions of cmp(a,b) may
|
||||||
|
make use of comparison of numerical or string components.
|
||||||
|
definitions using comparison of numbers or strings are usually
|
||||||
|
appropriate. For example, after
|
||||||
|
|
||||||
String comparison is performed via the strcmp() libc function.
|
obj point {x,y};
|
||||||
|
|
||||||
Note that this function is not a substitution for equality. The ==
|
if points with real components are to be partially ordered by their
|
||||||
operator always takes epsilon() into account when comparing numeric
|
euclidean distance from the origin, an appropriate point_rel
|
||||||
values. For example:
|
function may be that given by
|
||||||
|
|
||||||
> cmp(1, 1+epsilon()/2)
|
define point_rel(a,b) = sgn(a.x^2 + a.y^2 - b.x^2 - b.y^2);
|
||||||
-1
|
|
||||||
> 1 == 1+epsilon()/2
|
|
||||||
0
|
|
||||||
|
|
||||||
It should be noted epsilon() is used when comparing complex values.
|
A total "lexicographic" ordering is that given by:
|
||||||
|
|
||||||
Properties of cmp(a,b) for real or complex a and b are:
|
define point_rel(a,b) {
|
||||||
|
if (a.y != b.y)
|
||||||
|
return sgn(a.y - b.y);
|
||||||
|
return (a.x - b.x);
|
||||||
|
}
|
||||||
|
|
||||||
cmp(a + c, b + c) = cmp(a,b)
|
A comparison function that compares points analogously to
|
||||||
|
cmp(a,b) for real and complex numbers is that given by
|
||||||
|
|
||||||
|
define point_rel(P1, P2) {
|
||||||
|
return obj point = {sgn(P1.x-P2.x), sgn(P1.y-P2.y)};
|
||||||
|
}
|
||||||
|
|
||||||
|
The range of this function is the set of nine points with zero
|
||||||
|
or unit components.
|
||||||
|
|
||||||
|
|
||||||
|
Some properties of cmp(a,b) for real or complex a and b are:
|
||||||
|
|
||||||
|
cmp(a + c, b + c) = cmp(a, b)
|
||||||
|
|
||||||
cmp(a, b) == 0 if and only if a == b
|
cmp(a, b) == 0 if and only if a == b
|
||||||
|
|
||||||
cmp(b, a) = -cmp(a,b)
|
cmp(b, a) = -cmp(a, b)
|
||||||
|
|
||||||
if c is real or pure imaginary, cmp(c * a, c * b) = c * cmp(a,b)
|
if c is real or pure imaginary, cmp(c * a, c * b) = c * cmp(a,b)
|
||||||
|
|
||||||
cmp(a,b) == cmp(b,c) if and only if b is "between" a and c
|
Then a function that defines "b is between a and c" in an often useful
|
||||||
|
sense is
|
||||||
|
|
||||||
The numbers between 2 + 3i and 4 + 5i are those with real part between
|
define between(a,b,c) = (cmp(a,b) == cmp(b,c)).
|
||||||
2 and 4, imaginary part between 3 and 5; the numbers between 2 + 3i
|
|
||||||
and 4 + 3i are those with real part between 2 and 4, imaginary part = 3.
|
For example, in this sense, 3 + 4i is between 1 + 5i and 4 + 2i.
|
||||||
|
|
||||||
|
Note that using cmp to compare non-object values of different types,
|
||||||
|
for example, cmp(2, "2"), returns the null value.
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
> print cmp(3,4), cmp(4,3), cmp(4,4), cmp("a","b"), cmp("abcd","abc")
|
> print cmp(3,4), cmp(4,3), cmp(4,4), cmp("a","b"), cmp("abcd","abc")
|
||||||
@@ -84,7 +108,8 @@ LIMITS
|
|||||||
none
|
none
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
none
|
FLAG qrel(NUMBER *q1, NUMBER *q2)
|
||||||
|
FLAG zrel(ZVALUE z1, ZVALUE z2)
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
abs, epsilon, sgn
|
sgn, test, operator
|
||||||
|
@@ -5,10 +5,10 @@ SYNOPSIS
|
|||||||
comb(x, y)
|
comb(x, y)
|
||||||
|
|
||||||
TYPES
|
TYPES
|
||||||
x int
|
x integer
|
||||||
y int
|
y integer
|
||||||
|
|
||||||
return int
|
return integer
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Return the combinatorial number C(x,y) which is defined as:
|
Return the combinatorial number C(x,y) which is defined as:
|
||||||
@@ -33,7 +33,7 @@ LIMITS
|
|||||||
x-y < 2^24
|
x-y < 2^24
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
void zcomb(NUMBER x, y, *ret)
|
void zcomb(ZVALUE x, ZVALUE y, ZVALUE *res)
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
fact, perm
|
fact, perm
|
||||||
|
135
help/config
135
help/config
@@ -33,9 +33,16 @@ Configuration parameters
|
|||||||
"outround" sets rounding mode for printing of numbers
|
"outround" sets rounding mode for printing of numbers
|
||||||
"leadzero" enables/disables printing of 0 as in 0.5
|
"leadzero" enables/disables printing of 0 as in 0.5
|
||||||
"fullzero" enables/disables padding zeros as in .5000
|
"fullzero" enables/disables padding zeros as in .5000
|
||||||
"maxerr" maximum number of scan errors before abort
|
"maxscan" maximum number of scan errors before abort
|
||||||
"prompt" default interactive prompt
|
"prompt" default interactive prompt
|
||||||
"more" default interactive multi-line input prompt
|
"more" default interactive multi-line input prompt
|
||||||
|
"blkmaxprint" number of block octets to print, 0 means all
|
||||||
|
"blkverbose" TRUE=>print all lines, FALSE=>skip duplicates
|
||||||
|
"blkbase" block output base
|
||||||
|
"blkfmt" block output format
|
||||||
|
"lib_debug" calc library script debug level
|
||||||
|
"calc_debug" internal calc debug level
|
||||||
|
"user_debug" user defined debug level
|
||||||
|
|
||||||
|
|
||||||
The "all" config value allows one to save/restore the configuration
|
The "all" config value allows one to save/restore the configuration
|
||||||
@@ -90,6 +97,8 @@ Configuration parameters
|
|||||||
8: the opcodes for a new functions are displayed when the function
|
8: the opcodes for a new functions are displayed when the function
|
||||||
is successfully defined.
|
is successfully defined.
|
||||||
|
|
||||||
|
See also lib_debug, calc_debug and user_debug below for more debug levels.
|
||||||
|
|
||||||
The "display" parameter specifies the maximum number of digits after
|
The "display" parameter specifies the maximum number of digits after
|
||||||
the decimal point to be printed in real or exponential mode in
|
the decimal point to be printed in real or exponential mode in
|
||||||
normal unformatted printing (print, strprint, fprint) or in
|
normal unformatted printing (print, strprint, fprint) or in
|
||||||
@@ -128,7 +137,6 @@ Configuration parameters
|
|||||||
"oct" octal fractions
|
"oct" octal fractions
|
||||||
"bin" binary fractions
|
"bin" binary fractions
|
||||||
|
|
||||||
|
|
||||||
The "maxprint" parameter specifies the maximum number of elements to
|
The "maxprint" parameter specifies the maximum number of elements to
|
||||||
be displayed when a matrix or list is printed. The initial value is 16.
|
be displayed when a matrix or list is printed. The initial value is 16.
|
||||||
|
|
||||||
@@ -172,7 +180,7 @@ Configuration parameters
|
|||||||
|
|
||||||
Config ("tab") controls the printing of a tab before results
|
Config ("tab") controls the printing of a tab before results
|
||||||
automatically displayed when working interactively. It does not
|
automatically displayed when working interactively. It does not
|
||||||
affect the printing by the functions print, printf, etc. The inital
|
affect the printing by the functions print, printf, etc. The initial
|
||||||
"tab" value is 1.
|
"tab" value is 1.
|
||||||
|
|
||||||
The "quomod", "quo", "mod", "sqrt", "appr", "cfappr", "cfsim", and
|
The "quomod", "quo", "mod", "sqrt", "appr", "cfappr", "cfsim", and
|
||||||
@@ -232,11 +240,11 @@ Configuration parameters
|
|||||||
parameter is 0, so that, for example, if config("display") >= 2,
|
parameter is 0, so that, for example, if config("display") >= 2,
|
||||||
5/4 will print in "real" mode as 1.25.
|
5/4 will print in "real" mode as 1.25.
|
||||||
|
|
||||||
The maxerr value controls how many scan errors are allowed
|
The maxscan value controls how many scan errors are allowed
|
||||||
before the compiling phase of a computation is aborted. The initial
|
before the compiling phase of a computation is aborted. The initial
|
||||||
value of "maxerr" is 20. Setting maxerr to 0 disables this feature.
|
value of "maxscan" is 20. Setting maxscan to 0 disables this feature.
|
||||||
|
|
||||||
The default prompt when in teractive mode is "> ". One may change
|
The default prompt when in interactive mode is "> ". One may change
|
||||||
this prompt to a more cut-and-paste friendly prompt by:
|
this prompt to a more cut-and-paste friendly prompt by:
|
||||||
|
|
||||||
config("prompt", "; ")
|
config("prompt", "; ")
|
||||||
@@ -250,6 +258,121 @@ Configuration parameters
|
|||||||
|
|
||||||
config("more", ";; ")
|
config("more", ";; ")
|
||||||
|
|
||||||
|
The "blkmaxprint" config value limits the number of octets to print
|
||||||
|
for a block. A "blkmaxprint" of 0 means to print all octets of a
|
||||||
|
block, regardless of size.
|
||||||
|
|
||||||
|
The default is to print only the first 256 octets.
|
||||||
|
|
||||||
|
The "blkverbose" determines if all lines, including duplicates
|
||||||
|
should be printed. If TRUE, then all lines are printed. If false,
|
||||||
|
duplicate lines are skipped and only a "*" is printed in a style
|
||||||
|
similar to od. This config value has not meaning if "blkfmt" is "str".
|
||||||
|
|
||||||
|
The default value for "blkverbose" is FALSE: duplicate lines are
|
||||||
|
not printed.
|
||||||
|
|
||||||
|
The "blkbase" determines the base in which octets of a block
|
||||||
|
are printed. Possible values are:
|
||||||
|
|
||||||
|
"hexadecimal" Octets printed in 2 digit hex
|
||||||
|
"hex"
|
||||||
|
|
||||||
|
"octal" Octets printed in 3 digit octal
|
||||||
|
"oct"
|
||||||
|
|
||||||
|
"character" Octets printed as chars with non-printing
|
||||||
|
"char" chars as \123 or \n, \t, \r
|
||||||
|
|
||||||
|
"binary" Octets printed as 0 or 1 chars
|
||||||
|
"bin"
|
||||||
|
|
||||||
|
"raw" Octets printed as is, i.e. raw binary
|
||||||
|
"none"
|
||||||
|
|
||||||
|
The default "blkbase" is "hex".
|
||||||
|
|
||||||
|
The "blkfmt" determines for format of how block are printed:
|
||||||
|
|
||||||
|
"line" print in lines of up to 79 chars + newline
|
||||||
|
"lines"
|
||||||
|
|
||||||
|
"str" print as one long string
|
||||||
|
"string"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"od" print in od-like format, with leading offset,
|
||||||
|
"odstyle" followed by octets in the given base
|
||||||
|
"od_style"
|
||||||
|
|
||||||
|
"hd" print in hex dump format, with leading offset,
|
||||||
|
"hdstyle" followed by octets in the given base, followed
|
||||||
|
"hd_style" by chars or '.' if no-printable or blank
|
||||||
|
|
||||||
|
The default "blkfmt" is "hd".
|
||||||
|
|
||||||
|
With regards to "lib_debug", "calc_debug" and "user_debug":
|
||||||
|
higher absolute values result in more detailed debugging and
|
||||||
|
more verbose debug messages. The default value is 0 in which
|
||||||
|
a very amount of debugging will be performed with nil messages.
|
||||||
|
The -1 value is reserved for no debugging or messages. Any
|
||||||
|
value <-1 will perform debugging silently (presumably collecting
|
||||||
|
data to be displayed at a later time). Values >0 result in a
|
||||||
|
greater degree of debugging and more verbose messages.
|
||||||
|
|
||||||
|
The "lib_debug" is reserved by convention for calc library scripts.
|
||||||
|
This config parameter takes the place of the lib_debug global variable.
|
||||||
|
By convention, "lib_debug" has the following meanings:
|
||||||
|
|
||||||
|
<-1 no debug messages are printed though some internal
|
||||||
|
debug actions and information may be collected
|
||||||
|
|
||||||
|
-1 no debug messages are printed, no debug actions will be taken
|
||||||
|
|
||||||
|
0 only usage message regarding each important object are
|
||||||
|
printed at the time of the read (default)
|
||||||
|
|
||||||
|
>0 messages regarding each important object are
|
||||||
|
printed at the time of the read in addition
|
||||||
|
to other debug messages
|
||||||
|
|
||||||
|
The "calc_debug" is reserved by convention for internal calc routines.
|
||||||
|
The output of "calc_debug" will change from release to release.
|
||||||
|
Generally this value is used by calc wizards and by the regress.cal
|
||||||
|
routine (make check). By convention, "calc_debug" has the following
|
||||||
|
meanings:
|
||||||
|
|
||||||
|
<-1 reserved for future use
|
||||||
|
|
||||||
|
-1 no debug messages are printed, no debug actions will be taken
|
||||||
|
|
||||||
|
0 very little, if any debugging is performed (and then mostly
|
||||||
|
in alpha test code). The only output is as a result of
|
||||||
|
internal fatal errors (typically either math_error() or
|
||||||
|
exit() will be called). (default)
|
||||||
|
|
||||||
|
>0 a greater degree of debugging is performed and more
|
||||||
|
verbose messages are printed (regress.cal uses 1).
|
||||||
|
|
||||||
|
The "user_debug" is provided for use by users. Calc ignores this value
|
||||||
|
other than to set it to 0 by default (for both "oldstd" and "newstd").
|
||||||
|
No calc code or shipped library will change this value other than
|
||||||
|
during startup or during a config("all", xyz) call.
|
||||||
|
|
||||||
|
The following is suggested as a convention for use of "user_debug".
|
||||||
|
These are only suggestions: feel free to use it as you like:
|
||||||
|
|
||||||
|
<-1 no debug messages are printed though some internal
|
||||||
|
debug actions and information may be collected
|
||||||
|
|
||||||
|
-1 no debug messages are printed, no debug actions will be taken
|
||||||
|
|
||||||
|
0 very little, if any debugging is performed. The only output
|
||||||
|
are from fatal errors. (default)
|
||||||
|
|
||||||
|
>0 a greater degree of debugging is performed and more
|
||||||
|
verbose messages are printed
|
||||||
|
|
||||||
The following are synonyms for true:
|
The following are synonyms for true:
|
||||||
|
|
||||||
"on" "yes" "y" "true" "t" "1" any non-zero number
|
"on" "yes" "y" "true" "t" "1" any non-zero number
|
||||||
|
@@ -14,6 +14,7 @@ TYPES
|
|||||||
return real, complex, or matrix
|
return real, complex, or matrix
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
|
||||||
For real x, conj(x) returns x.
|
For real x, conj(x) returns x.
|
||||||
|
|
||||||
For complex x, conj(x) returns re(x) - im(x) * 1i.
|
For complex x, conj(x) returns re(x) - im(x) * 1i.
|
||||||
@@ -21,6 +22,11 @@ DESCRIPTION
|
|||||||
For matrix x, conj(x) returns a matrix of the same structure as x
|
For matrix x, conj(x) returns a matrix of the same structure as x
|
||||||
in which each element t of x has been replaced by conj(t).
|
in which each element t of x has been replaced by conj(t).
|
||||||
|
|
||||||
|
For xx objects, xx_conj(a) may return any type of value, but
|
||||||
|
for the properties usually expected of conjugates, xx_conj(a)
|
||||||
|
would return an xx object in which each number component is the
|
||||||
|
conjugate of the corresponding component of a.
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
> print conj(3), conj(3 + 4i)
|
> print conj(3), conj(3 + 4i)
|
||||||
3 3-4i
|
3 3-4i
|
||||||
|
48
help/contrib
Normal file
48
help/contrib
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
We welcome and encourage you to send us:
|
||||||
|
|
||||||
|
* calc scripts
|
||||||
|
* any builtin functions that you have modified or written
|
||||||
|
* custom functions that you have modified or written
|
||||||
|
* any other source code modifications
|
||||||
|
|
||||||
|
Prior to doing so, you should consider trying your changes on the most
|
||||||
|
recent alpha test code. To obtain the most recent code, look under
|
||||||
|
|
||||||
|
http://reality.sgi.com/chongo/calc/
|
||||||
|
|
||||||
|
You should also consider joining the calc testing group by sending 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.
|
||||||
|
|
||||||
|
In order to consider integrating your code, we need:
|
||||||
|
|
||||||
|
* help files (documentation)
|
||||||
|
* CHANGES text (brief description of what it does)
|
||||||
|
* regress.cal test (to test non-custom code)
|
||||||
|
* your source code and/or source code changes (:-))
|
||||||
|
|
||||||
|
The best way to send us new code, if your changes are small, is
|
||||||
|
via a patch (diff -c from the latest alpha code to your code).
|
||||||
|
If your change is large, you should send entire files (either
|
||||||
|
as a diff -c /dev/null your-file patch, or as a uuencoded and
|
||||||
|
gziped (or compressed) tar file).
|
||||||
|
|
||||||
|
You should send submissions to:
|
||||||
|
|
||||||
|
calc-tester@postofc.corp.sgi.com
|
||||||
|
|
||||||
|
Thanks for considering submitting code to calc. Calc is a collective
|
||||||
|
work by a number of people. It would not be what it is today without
|
||||||
|
your efforts and submissions!
|
||||||
|
|
||||||
|
Landon Curt Noll <chongo@toad.com> /\oo/\
|
2
help/cos
2
help/cos
@@ -26,7 +26,7 @@ EXAMPLE
|
|||||||
.5 0 -1
|
.5 0 -1
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
eps > 0
|
none
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qcos(NUMBER *x, NUMBER *eps)
|
NUMBER *qcos(NUMBER *x, NUMBER *eps)
|
||||||
|
@@ -21,8 +21,7 @@ EXAMPLE
|
|||||||
1.54308 1.5430806348 1.543080634815244 1.54308063481524377848
|
1.54308 1.5430806348 1.543080634815244 1.54308063481524377848
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qcosh(NUMBER *x, NUMBER *eps)
|
NUMBER *qcosh(NUMBER *x, NUMBER *eps)
|
||||||
|
6
help/cot
6
help/cot
@@ -19,12 +19,10 @@ EXAMPLE
|
|||||||
.64209 .6420926159 .642092615934331 .64209261593433070301
|
.64209 .6420926159 .642092615934331 .64209261593433070301
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
x != 0
|
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qcot(NUMBER *x, *eps)
|
NUMBER *qcot(NUMBER *x, NUMBER *eps)
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
sin, cos, tan, sec, csc, epsilon
|
sin, cos, tan, sec, csc, epsilon
|
||||||
|
@@ -21,9 +21,7 @@ EXAMPLE
|
|||||||
1.31304 1.3130352855 1.313035285499331 1.31303528549933130364
|
1.31304 1.3130352855 1.313035285499331 1.31303528549933130364
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
unlike sin and cos, x must be real
|
none
|
||||||
x != 0
|
|
||||||
eps > 0
|
|
||||||
|
|
||||||
LIBRARY
|
LIBRARY
|
||||||
NUMBER *qcoth(NUMBER *x, NUMBER *eps)
|
NUMBER *qcoth(NUMBER *x, NUMBER *eps)
|
||||||
|
@@ -8,7 +8,7 @@ TYPES
|
|||||||
x list or matrix
|
x list or matrix
|
||||||
y string
|
y string
|
||||||
|
|
||||||
return int
|
return integer
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
For count(x, y), y is to be the name of a user-defined function;
|
For count(x, y), y is to be the name of a user-defined function;
|
||||||
@@ -28,4 +28,4 @@ LIBRARY
|
|||||||
none
|
none
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
XXX - fill in
|
select, modify
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user