Back to index

radiance  4R0+20100331
Classes | Defines | Typedefs | Functions | Variables
calfunc.c File Reference
#include "copyright.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include "rterror.h"
#include "calcomp.h"

Go to the source code of this file.

Classes

struct  activation

Defines

#define AFLAGSIZ   (8*sizeof(unsigned long))
#define ALISTSIZ   6 /* maximum saved argument list */
#define MAXLIB   64 /* maximum number of library functions */
#define resolve(ep)   ((ep)->type==VAR?(ep)->v.ln:argf((ep)->v.chan))

Typedefs

typedef struct activation ACTIVATION

Functions

static double libfunc (char *fname, VARDEF *vp)
static double l_if (char *)
static double l_select (char *)
static double l_rand (char *)
static double l_floor (char *)
static double l_ceil (char *)
static double l_sqrt (char *)
static double l_sin (char *)
static double l_cos (char *)
static double l_tan (char *)
static double l_asin (char *)
static double l_acos (char *)
static double l_atan (char *)
static double l_atan2 (char *)
static double l_exp (char *)
static double l_log (char *)
static double l_log10 (char *)
int fundefined (char *fname)
double funvalue (char *fname, int n, double *a)
void funset (char *fname, int nargs, int assign, double(*fptr)(char *))
int nargum ()
double argument (int n)
VARDEF * argf (int n)
char * argfun (int n)
double efunc (EPNODE *ep)
LIBRliblookup (char *fname)

Variables

static const char RCSid [] = "$Id: calfunc.c,v 2.15 2006/05/10 15:21:20 greg Exp $"
static ACTIVATIONcuract = NULL
static LIBR library [MAXLIB]
static int libsize = 16

Class Documentation

struct activation

Definition at line 27 of file calfunc.c.

Collaboration diagram for activation:
Class Members
unsigned long an
double * ap
EPNODE * fun
char * name
struct activation * prev

Define Documentation

#define AFLAGSIZ   (8*sizeof(unsigned long))

Definition at line 24 of file calfunc.c.

#define ALISTSIZ   6 /* maximum saved argument list */

Definition at line 25 of file calfunc.c.

#define MAXLIB   64 /* maximum number of library functions */

Definition at line 40 of file calfunc.c.

#define resolve (   ep)    ((ep)->type==VAR?(ep)->v.ln:argf((ep)->v.chan))

Definition at line 72 of file calfunc.c.


Typedef Documentation

typedef struct activation ACTIVATION

Function Documentation

VARDEF* argf ( int  n)

Definition at line 224 of file calfunc.c.

{
    register ACTIVATION  *actp;
    register EPNODE  *ep;

    for (actp = curact; actp != NULL; actp = actp->prev) {

       if (n <= 0)
           break;

       if (actp->fun == NULL)
           goto badarg;

       if ((ep = ekid(actp->fun, n)) == NULL) {
           eputs(actp->name);
           eputs(": too few arguments\n");
           quit(1);
       }
       if (ep->type == VAR)
           return(ep->v.ln);                     /* found it */

       if (ep->type != ARG)
           goto badarg;

       n = ep->v.chan;                           /* try previous context */
    }
    eputs("Bad call to argf!\n");
    quit(1);

badarg:
    eputs(actp->name);
    eputs(": argument not a function\n");
    quit(1);
       return NULL; /* pro forma return */
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* argfun ( int  n)

Definition at line 263 of file calfunc.c.

{
    return(argf(n)->name);
}

Here is the call graph for this function:

double argument ( int  n)

Definition at line 192 of file calfunc.c.

{
    register ACTIVATION  *actp = curact;
    register EPNODE  *ep = NULL;
    double  aval;

    if (actp == NULL || --n < 0) {
       eputs("Bad call to argument!\n");
       quit(1);
    }
                                          /* already computed? */
    if (n < AFLAGSIZ && 1L<<n & actp->an)
       return(actp->ap[n]);

    if (actp->fun == NULL || (ep = ekid(actp->fun, n+1)) == NULL) {
       eputs(actp->name);
       eputs(": too few arguments\n");
       quit(1);
    }
    curact = actp->prev;                  /* pop environment */
    aval = evalue(ep);                           /* compute argument */
    curact = actp;                        /* push back environment */
    if (n < ALISTSIZ) {                          /* save value */
       actp->ap[n] = aval;
       actp->an |= 1L<<n;
    }
    return(aval);
}

Here is the call graph for this function:

Here is the caller graph for this function:

double efunc ( EPNODE ep)

Definition at line 271 of file calfunc.c.

{
    ACTIVATION  act;
    double  alist[ALISTSIZ];
    double  rval;
    register VARDEF  *dp;
                                   /* push environment */
    dp = resolve(ep->v.kid);
    act.name = dp->name;
    act.prev = curact;
    act.ap = alist;
    act.an = 0;
    act.fun = ep;
    curact = &act;

    if (dp->def == NULL || dp->def->v.kid->type != FUNC)
       rval = libfunc(act.name, dp);
    else
       rval = evalue(dp->def->v.kid->sibling);
    
    curact = act.prev;                    /* pop environment */
    return(rval);
}

Here is the call graph for this function:

int fundefined ( char *  fname)

Definition at line 76 of file calfunc.c.

{
    register LIBR  *lp;
    register VARDEF  *vp;

    if ((vp = varlookup(fname)) != NULL && vp->def != NULL
              && vp->def->v.kid->type == FUNC)
       return(nekids(vp->def->v.kid) - 1);
    lp = vp != NULL ? vp->lib : liblookup(fname);
    if (lp == NULL)
       return(0);
    return(lp->nargs);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void funset ( char *  fname,
int  nargs,
int  assign,
double (*)(char *)  fptr 
)

Definition at line 124 of file calfunc.c.

{
    int  oldlibsize = libsize;
    char *cp;
    register LIBR  *lp;
                                          /* check for context */
    for (cp = fname; *cp; cp++)
       ;
    if (cp == fname)
       return;
    if (cp[-1] == CNTXMARK)
       *--cp = '\0';
    if ((lp = liblookup(fname)) == NULL) {       /* insert */
       if (libsize >= MAXLIB) {
           eputs("Too many library functons!\n");
           quit(1);
       }
       for (lp = &library[libsize]; lp > library; lp--)
           if (strcmp(lp[-1].fname, fname) > 0) {
              lp[0].fname = lp[-1].fname;
              lp[0].nargs = lp[-1].nargs;
              lp[0].atyp = lp[-1].atyp;
              lp[0].f = lp[-1].f;
           } else
              break;
       libsize++;
    }
    if (fptr == NULL) {                          /* delete */
       while (lp < &library[libsize-1]) {
           lp[0].fname = lp[1].fname;
           lp[0].nargs = lp[1].nargs;
           lp[0].atyp = lp[1].atyp;
           lp[0].f = lp[1].f;
           lp++;
       }
       libsize--;
    } else {                              /* or assign */
       lp[0].fname = fname;        /* string must be static! */
       lp[0].nargs = nargs;
       lp[0].atyp = assign;
       lp[0].f = fptr;
    }
    if (libsize != oldlibsize)
       libupdate(fname);                  /* relink library */
}

Here is the call graph for this function:

Here is the caller graph for this function:

double funvalue ( char *  fname,
int  n,
double *  a 
)

Definition at line 93 of file calfunc.c.

{
    ACTIVATION  act;
    register VARDEF  *vp;
    double  rval;
                                   /* push environment */
    act.name = fname;
    act.prev = curact;
    act.ap = a;
    if (n >= AFLAGSIZ)
       act.an = ~0;
    else
       act.an = (1L<<n)-1;
    act.fun = NULL;
    curact = &act;

    if ((vp = varlookup(fname)) == NULL || vp->def == NULL
              || vp->def->v.kid->type != FUNC)
       rval = libfunc(fname, vp);
    else
       rval = evalue(vp->def->v.kid->sibling);

    curact = act.prev;                    /* pop environment */
    return(rval);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static double l_acos ( char *  nm)

Definition at line 464 of file calfunc.c.

{
    return(acos(argument(1)));
}

Here is the call graph for this function:

static double l_asin ( char *  nm) [static]

Definition at line 457 of file calfunc.c.

{
    return(asin(argument(1)));
}

Here is the call graph for this function:

static double l_atan ( char *  nm)

Definition at line 471 of file calfunc.c.

{
    return(atan(argument(1)));
}

Here is the call graph for this function:

static double l_atan2 ( char *  nm)

Definition at line 478 of file calfunc.c.

{
    return(atan2(argument(1), argument(2)));
}

Here is the call graph for this function:

static double l_ceil ( char *  nm)

Definition at line 422 of file calfunc.c.

{
    return(ceil(argument(1)));
}

Here is the call graph for this function:

static double l_cos ( char *  nm)

Definition at line 443 of file calfunc.c.

{
    return(cos(argument(1)));
}

Here is the call graph for this function:

static double l_exp ( char *  nm) [static]

Definition at line 485 of file calfunc.c.

{
    return(exp(argument(1)));
}

Here is the call graph for this function:

static double l_floor ( char *  nm) [static]

Definition at line 415 of file calfunc.c.

{
    return(floor(argument(1)));
}

Here is the call graph for this function:

static double l_if ( char *  nm) [static]

Definition at line 375 of file calfunc.c.

{
    if (argument(1) > 0.0)
       return(argument(2));
    else
       return(argument(3));
}

Here is the call graph for this function:

static double l_log ( char *  nm)

Definition at line 492 of file calfunc.c.

{
    return(log(argument(1)));
}

Here is the call graph for this function:

static double l_log10 ( char *  nm)

Definition at line 499 of file calfunc.c.

{
    return(log10(argument(1)));
}

Here is the call graph for this function:

static double l_rand ( char *  nm)

Definition at line 402 of file calfunc.c.

{
    double  x;

    x = argument(1);
    x *= 1.0/(1.0 + x*x) + 2.71828182845904;
    x += .785398163397447 - floor(x);
    x = 1e5 / x;
    return(x - floor(x));
}

Here is the call graph for this function:

static double l_select ( char *  nm)

Definition at line 386 of file calfunc.c.

{
       register int  n;

       n = (int)(argument(1) + .5);
       if (n == 0)
              return(nargum()-1);
       if (n < 1 || n > nargum()-1) {
              errno = EDOM;
              return(0.0);
       }
       return(argument(n+1));
}

Here is the call graph for this function:

static double l_sin ( char *  nm) [static]

Definition at line 436 of file calfunc.c.

{
    return(sin(argument(1)));
}

Here is the call graph for this function:

static double l_sqrt ( char *  nm) [static]

Definition at line 429 of file calfunc.c.

{
    return(sqrt(argument(1)));
}

Here is the call graph for this function:

static double l_tan ( char *  nm)

Definition at line 450 of file calfunc.c.

{
    return(tan(argument(1)));
}

Here is the call graph for this function:

static double libfunc ( char *  fname,
VARDEF *  vp 
) [static]

Definition at line 327 of file calfunc.c.

{
    register LIBR  *lp;
    double  d;
    int  lasterrno;

    if (vp != NULL)
       lp = vp->lib;
    else
       lp = liblookup(fname);
    if (lp == NULL) {
       eputs(fname);
       eputs(": undefined function\n");
       quit(1);
    }
    lasterrno = errno;
    errno = 0;
    d = (*lp->f)(lp->fname);
#ifdef  isnan
    if (errno == 0)
       if (isnan(d))
           errno = EDOM;
       else if (isinf(d))
           errno = ERANGE;
#endif
    if (errno == EDOM || errno == ERANGE) {
       wputs(fname);
       if (errno == EDOM)
              wputs(": domain error\n");
       else if (errno == ERANGE)
              wputs(": range error\n");
       else
              wputs(": error in call\n");
       return(0.0);
    }
    errno = lasterrno;
    return(d);
}

Here is the call graph for this function:

Here is the caller graph for this function:

LIBR* liblookup ( char *  fname)

Definition at line 298 of file calfunc.c.

{
    int  upper, lower;
    register int  cm, i;

    lower = 0;
    upper = cm = libsize;

    while ((i = (lower + upper) >> 1) != cm) {
       cm = strcmp(fname, library[i].fname);
       if (cm > 0)
           lower = i;
       else if (cm < 0)
           upper = i;
       else
           return(&library[i]);
       cm = i;
    }
    return(NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int nargum ( void  )

Definition at line 176 of file calfunc.c.

{
    register int  n;

    if (curact == NULL)
       return(0);
    if (curact->fun == NULL) {
       for (n = 0; (1L<<n) & curact->an; n++)
           ;
       return(n);
    }
    return(nekids(curact->fun) - 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

ACTIVATION* curact = NULL [static]

Definition at line 35 of file calfunc.c.

LIBR library[MAXLIB] [static]
Initial value:
 {
    { "acos", 1, ':', l_acos },
    { "asin", 1, ':', l_asin },
    { "atan", 1, ':', l_atan },
    { "atan2", 2, ':', l_atan2 },
    { "ceil", 1, ':', l_ceil },
    { "cos", 1, ':', l_cos },
    { "exp", 1, ':', l_exp },
    { "floor", 1, ':', l_floor },
    { "if", 3, ':', l_if },
    { "log", 1, ':', l_log },
    { "log10", 1, ':', l_log10 },
    { "rand", 1, ':', l_rand },
    { "select", 1, ':', l_select },
    { "sin", 1, ':', l_sin },
    { "sqrt", 1, ':', l_sqrt },
    { "tan", 1, ':', l_tan },
}

Definition at line 51 of file calfunc.c.

int libsize = 16 [static]

Definition at line 70 of file calfunc.c.

const char RCSid[] = "$Id: calfunc.c,v 2.15 2006/05/10 15:21:20 greg Exp $" [static]

Definition at line 2 of file calfunc.c.