home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #4 / amigaacscoverdisc1998-041998.iso / utilities / shareware / dev / ucb_logoppc / source / math.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-25  |  15.5 KB  |  689 lines

  1. /*
  2.  *      math.c          logo math functions module              dvb
  3.  *
  4.  * Copyright (C) 1993 by the Regents of the University of California
  5.  *
  6.  *      This program is free software; you can redistribute it and/or modify
  7.  *      it under the terms of the GNU General Public License as published by
  8.  *      the Free Software Foundation; either version 2 of the License, or
  9.  *      (at your option) any later version.
  10.  *
  11.  *      This program is distributed in the hope that it will be useful,
  12.  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *      GNU General Public License for more details.
  15.  *
  16.  *      You should have received a copy of the GNU General Public License
  17.  *      along with this program; if not, write to the Free Software
  18.  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  */
  21.  
  22. #include "logo.h"
  23. #include "globals.h"
  24. #include <signal.h>
  25. #include <setjmp.h>
  26. #include <math.h>
  27.  
  28. #define isdigit(dig)    (dig >= '0' && dig <= '9')
  29.  
  30. int numberp(NODE *snd) {
  31.     int dl,dr, pcnt, plen;
  32.     char *p;
  33.  
  34.     if (is_number(snd)) return(1);
  35.  
  36.     snd = cnv_node_to_strnode(snd);
  37.     if (snd == UNBOUND) return(0);
  38.  
  39.     p = getstrptr(snd); plen = getstrlen(snd); pcnt = dl = dr = 0;
  40.     if (plen >= MAX_NUMBER) {
  41.    return(0);
  42.     }
  43.  
  44.     if (pcnt < plen && *p == '-')
  45.    p++, pcnt++;
  46.  
  47.     while (pcnt < plen && isdigit(*p))
  48.    p++, pcnt++, dl++;
  49.  
  50.     if (pcnt < plen && *p == '.') {
  51.    p++, pcnt++;
  52.    while (pcnt < plen && isdigit(*p))
  53.        p++, pcnt++, dr++;
  54.     }
  55.  
  56.     if (pcnt < plen && (dl || dr) && (*p == 'E' || *p == 'e')) {
  57.    p++, pcnt++;
  58.  
  59.    if (pcnt < plen && (*p == '+' || *p == '-'))
  60.        p++, pcnt++;
  61.  
  62.    while (pcnt < plen && isdigit(*p))
  63.        p++, pcnt++, dr++;
  64.     }
  65.  
  66.     if ((dl == 0 && dr == 0) || pcnt != plen)
  67.    return (0);
  68.     else
  69.    return (dr + 1);
  70. }
  71.  
  72. NODE *lrandom(NODE *arg) {
  73.    NODE *val;
  74.    long r;
  75.  
  76.    val = pos_int_arg(arg);
  77.    if (NOT_THROWING) {
  78. #ifdef HAVE_SRANDOM
  79.       r = (getint(val) == 0 ? 0 : random() % getint(val));
  80. #else
  81.            r = (((long)rand()) << 15) | rand();
  82.       r = (getint(val) == 0 ? 0 : r % getint(val));
  83. #endif
  84.       val = newnode(INT);
  85. #ifdef AMIGA
  86.    if (r<0) r=-r;
  87. #endif
  88.       setint(val, (FIXNUM)r);
  89.       return(val);
  90.    } else return(UNBOUND);
  91. }
  92.  
  93. NODE *lrerandom(NODE *arg) {
  94.    int seed=1;
  95.  
  96.    if (arg != NIL) {
  97.       seed = int_arg(arg);
  98.    }
  99.    if (NOT_THROWING) {
  100. #ifdef HAVE_SRANDOM
  101.       srandom((int)seed);
  102. #else
  103.       srand((int)seed);
  104. #endif
  105.    }
  106.    return(UNBOUND);
  107. }
  108.  
  109. jmp_buf oflo_buf;
  110. BOOLEAN handling_oflo = FALSE;
  111.  
  112. #if defined(__ZTC__) || defined(WIN32)
  113. #define sig_arg 0
  114. void handle_oflo(int sig) {
  115. #else
  116. #define sig_arg
  117. RETSIGTYPE handle_oflo() {
  118. #endif
  119.     signal(SIGFPE, handle_oflo);
  120.     if (handling_oflo) longjmp(oflo_buf,1);
  121. }
  122.  
  123. void math_init() {
  124.     signal(SIGFPE, handle_oflo);
  125. }
  126.  
  127. #ifdef HAVE_MATHERR
  128. int matherr(struct exception *x) {
  129.     if (x->type == UNDERFLOW) return(1);
  130.     longjmp(oflo_buf,1);
  131. }
  132. #endif
  133.  
  134. #ifdef mac
  135. FLONUM degrad = 0.017453292520;
  136. #else
  137. FLONUM degrad = 3.141592653589793227020265931059839203954/180.0;
  138. #endif
  139.  
  140. #if defined(mac)||defined(ibm)
  141. #define errchk(x) {errno = 0; x; if (errno) err_logo(BAD_DATA_UNREC,arg);}
  142. #include <errno.h>
  143. #else
  144. #define errchk(x) x
  145. #endif
  146.  
  147. NODE *binary(NODE *args, char fcn) {
  148.     NODE *arg, *val;
  149.     BOOLEAN imode;
  150.     FIXNUM iarg = 0, ival = 0, oval, nval;
  151.     FLONUM farg = 0.0, fval = 0.0;
  152.     int sign, wantint=0;
  153.  
  154.     /* Force imode, arg and fval into the stack because otherwise they may be
  155.        clobbered during setjmp/longjmp. Especially on Sparc. */
  156.     (void)&imode; (void)&arg; (void)&fval;
  157.  
  158.     if (fcn == '%' || fcn == 'm')
  159.    arg = integer_arg(args);
  160.     else
  161.    arg = numeric_arg(args);
  162.     args = cdr(args);
  163.     if (stopping_flag == THROWING) return UNBOUND;
  164.     if (nodetype(arg) == INT) {
  165.    imode = TRUE;
  166.    ival = getint(arg);
  167.     } else {
  168.    imode = FALSE;
  169.    fval = getfloat(arg);
  170.     }
  171.     if (args == NIL) {    /* one argument supplied */
  172.       if (imode)
  173.    switch(fcn) {
  174.      case '-': ival = -ival; break;
  175.      case '~': ival = ~ival; break;
  176.      case 's':
  177.      case 'c':
  178.      case 't':
  179.      case 'S':
  180.      case 'C':
  181.      case 'T':
  182.      case 'q':
  183.      case 'e':
  184.      case 'g':
  185.      case 'n':
  186.      case '/':
  187.        imode = FALSE;
  188.        fval = (FLONUM)ival;
  189.        break;
  190.    }
  191.       if (imode == FALSE) {
  192.        if (!setjmp(oflo_buf)) {
  193.    switch(fcn) {
  194.      case '-': fval = -fval; break;
  195.      case '/':
  196.        if (fval == 0.0)
  197.       err_logo(BAD_DATA_UNREC,arg);
  198.        else
  199.       fval = 1/fval;
  200.        break;
  201.      case '~': err_logo(BAD_DATA_UNREC,arg); break;
  202.      case 'c':
  203.        fval = 90.0 - fval;
  204.      case 's':
  205.        /* Kahan sez we can't just multiply any old
  206.         * angle by degrad, but have to get into the
  207.         * range 0-45 first */
  208.        sign = (fval < 0.0);
  209.        if (sign) fval = -fval;
  210. #ifndef HAVE_DREM
  211.        fval = fmod(fval,360.0);
  212. #else
  213.        fval = drem(fval,360.0);
  214. #endif
  215.        if (fval > 180.0) {
  216.       fval -= 180.0;
  217.       sign = !sign;
  218.        }
  219.        if (fval > 90.0) fval = 180.0 - fval;
  220.        if (fval > 45.0)
  221.       fval = cos((90.0-fval)*degrad);
  222.        else
  223.       fval = sin(fval*degrad);
  224.        if (sign) fval = -fval;
  225.        break;
  226.      case 't': fval = atan(fval)/degrad; break;
  227.      case 'S': fval = sin(fval); break;
  228.      case 'C': fval = cos(fval); break;
  229.      case 'T': fval = atan(fval); break;
  230.      case 'q': errchk(fval = sqrt(fval)); break;
  231.      case 'e': errchk(fval = exp(fval)); break;
  232.      case 'g': errchk(fval = log10(fval)); break;
  233.      case 'n': errchk(fval = log(fval)); break;
  234.      case 'r':
  235.        fval += (fval < 0 ? -0.5 : 0.5);
  236.      case 'i':
  237.        handling_oflo = TRUE;
  238.        if (fval > (FLONUM)MAXLOGOINT ||
  239.           fval < -(FLONUM)MAXLOGOINT)
  240.       handle_oflo(sig_arg);
  241.        ival = (FIXNUM)fval;
  242.        imode = TRUE;
  243.        handling_oflo = FALSE;
  244.        break;
  245.    }
  246.        } else {   /* overflow */
  247.        if (fcn == 'r' || fcn == 'i') {
  248.          if (fval < 0.0)
  249.       fval = ceil(fval);
  250.          else
  251.       fval = floor(fval);
  252.        } else
  253.       err_logo(BAD_DATA_UNREC,arg);
  254.        }
  255.       }      /* end float case */
  256.     }     /* end monadic */
  257.     while (args != NIL && NOT_THROWING) {
  258.    if (fcn == '%' || fcn == 'm')
  259.        arg = integer_arg(args);
  260.    else
  261.        arg = numeric_arg(args);
  262.    args = cdr(args);
  263.    if (stopping_flag == THROWING) return UNBOUND;
  264.  
  265.    if (nodetype(arg) == INT) {
  266.        if (imode) iarg = getint(arg);
  267.        else farg = (FLONUM)getint(arg);
  268.    } else {
  269.        if (imode) {
  270.       fval = (FLONUM)ival;
  271.       imode = FALSE;
  272.        }
  273.        farg = getfloat(arg);
  274.    }
  275.  
  276.    if (imode) {
  277.        oval = ival;
  278.        handling_oflo = TRUE;
  279.        if (setjmp(oflo_buf) == 0) {
  280.         switch(fcn) {
  281.          case '-': iarg = -iarg;
  282.          case '+':
  283.       if (iarg < 0) {
  284.           nval = ival + iarg;
  285.           if (nval >= ival)
  286.          handle_oflo(sig_arg);
  287.           else ival = nval;
  288.       } else {
  289.           nval = ival + iarg;
  290.           if (nval < ival)
  291.          handle_oflo(sig_arg);
  292.           else ival = nval;
  293.       }
  294.       break;
  295.          case '/':
  296.       if (iarg == 0)
  297.         err_logo(BAD_DATA_UNREC,arg);
  298.       else
  299.         if (ival % iarg != 0) {
  300.           imode = FALSE;
  301.           fval = (FLONUM)ival;
  302.           farg = (FLONUM)iarg;
  303.         }
  304.         else ival /= iarg;
  305.         break;
  306.          case '%':
  307.       ival %= iarg;
  308.       break;
  309.          case 'm':
  310.       ival %= iarg;
  311.       if ((ival < 0) != (iarg < 0))
  312.           ival += iarg;
  313.       break;
  314.          case '&': ival &= iarg; break;
  315.          case '|': ival |= iarg; break;
  316.          case '^': ival ^= iarg; break;
  317.          case 'a':
  318.          case 'l':
  319.       if (iarg < 0) {
  320.         if (fcn == 'a')
  321.           ival >>= -iarg;
  322.         else
  323.           ival = (unsigned)ival
  324.          >> -iarg;
  325.       } else
  326.         ival <<= iarg;
  327.       break;
  328.          case '*':
  329.       if (ival < SAFEINT && ival > -SAFEINT &&
  330.           iarg < SAFEINT && iarg > -SAFEINT) {
  331.           ival *= iarg;
  332.           break;
  333.       }
  334.       wantint++;
  335.          default: /* math library */
  336.       imode = FALSE;
  337.       fval = (FLONUM)ival;
  338.       farg = (FLONUM)iarg;
  339.         }
  340.        } else {    /* integer overflow detected */
  341.       imode = FALSE;
  342.       fval = (FLONUM)oval;
  343.       farg = (FLONUM)iarg;
  344.        }
  345.        handling_oflo = FALSE;
  346.    }
  347.    if (imode == FALSE) {
  348.      handling_oflo = TRUE;
  349.      if (setjmp(oflo_buf) == 0) {
  350.        switch(fcn) {
  351.          case '+': fval += farg; break;
  352.          case '-': fval -= farg; break;
  353.          case '*':
  354.       fval *= farg;
  355.       if (wantint) {
  356.           wantint = 0;
  357.           if (fval <= MAXLOGOINT && fval >= -MAXLOGOINT) {
  358.          imode = TRUE;
  359.          ival = fval;
  360.           }
  361.       }
  362.       break;
  363.          case '/': if (farg == 0.0)
  364.             err_logo(BAD_DATA_UNREC,arg);
  365.           else
  366.             fval /= farg;
  367.           break;
  368.          case 't':
  369.       errchk(fval = atan2(farg,fval)/degrad);
  370.       break;
  371.          case 'T':
  372.       errchk(fval = atan2(farg,fval));
  373.       break;
  374.          case 'p':
  375.       errchk(fval = pow(fval,farg));
  376.       break;
  377.          default: /* logical op */
  378.       if (nodetype(arg) == INT)
  379.         err_logo(BAD_DATA_UNREC, make_floatnode(fval));
  380.       else
  381.         err_logo(BAD_DATA_UNREC,arg);
  382.        }
  383.      } else {    /* floating overflow detected */
  384.        err_logo(BAD_DATA_UNREC,arg);
  385.      }
  386.      handling_oflo = FALSE;
  387.    }    /* end floating point */
  388.     } /* end dyadic */
  389.     if (NOT_THROWING) {
  390.    if (imode) {
  391.        val = newnode(INT);
  392.        setint(val, ival);
  393.    } else {
  394.        val = newnode(FLOATT);
  395.        setfloat(val, fval);
  396.    }
  397.    return(val);
  398.     }
  399.     return(UNBOUND);
  400. }
  401.  
  402. NODE *ladd(NODE *args) {
  403.     if (args == NIL) return make_intnode(0L);
  404.     return(binary(args, '+'));
  405. }
  406.  
  407. NODE *lsub(NODE *args) {
  408.     return(binary(args, '-'));
  409. }
  410.  
  411. NODE *lmul(NODE *args) {
  412.     if (args == NIL) return make_intnode(1L);
  413.     return(binary(args, '*'));
  414. }
  415.  
  416. NODE *ldivide(NODE *args) {
  417.     return(binary(args, '/'));
  418. }
  419.  
  420. NODE *lremainder(NODE *args) {
  421.     return(binary(args, '%'));
  422. }
  423.  
  424. NODE *lmodulo(NODE *args) {
  425.     return(binary(args, 'm'));
  426. }
  427.  
  428. NODE *lbitand(NODE *args) {
  429.     if (args == NIL) return make_intnode(-1);
  430.     return(binary(args, '&'));
  431. }
  432.  
  433. NODE *lbitor(NODE *args) {
  434.     if (args == NIL) return make_intnode(0);
  435.     return(binary(args, '|'));
  436. }
  437.  
  438. NODE *lbitxor(NODE *args) {
  439.     if (args == NIL) return make_intnode(0);
  440.     return(binary(args, '^'));
  441. }
  442.  
  443. NODE *lashift(NODE *args) {
  444.     return(binary(args, 'a'));
  445. }
  446.  
  447. NODE *llshift(NODE *args) {
  448.     return(binary(args, 'l'));
  449. }
  450.  
  451. NODE *lbitnot(NODE *args) {
  452.     return(binary(args, '~'));
  453. }
  454.  
  455. NODE *lsin(NODE *args) {
  456.     return(binary(args, 's'));
  457. }
  458.  
  459. NODE *lcos(NODE *args) {
  460.     return(binary(args, 'c'));
  461. }
  462.  
  463. NODE *latan(NODE *args) {
  464.     return(binary(args, 't'));
  465. }
  466.  
  467. NODE *lradsin(NODE *args) {
  468.     return(binary(args, 'S'));
  469. }
  470.  
  471. NODE *lradcos(NODE *args) {
  472.     return(binary(args, 'C'));
  473. }
  474.  
  475. NODE *lradatan(NODE *args) {
  476.     return(binary(args, 'T'));
  477. }
  478.  
  479. NODE *lsqrt(NODE *args) {
  480.     return(binary(args, 'q'));
  481. }
  482.  
  483. NODE *linteg(NODE *args) {
  484.     return(binary(args, 'i'));
  485. }
  486.  
  487. NODE *lround(NODE *args) {
  488.     return(binary(args, 'r'));
  489. }
  490.  
  491. NODE *lexp(NODE *args) {
  492.     return(binary(args, 'e'));
  493. }
  494.  
  495. NODE *llog10(NODE *args) {
  496.     return(binary(args, 'g'));
  497. }
  498.  
  499. NODE *lln(NODE *args) {
  500.     return(binary(args, 'n'));
  501. }
  502.  
  503. NODE *lpower(NODE *args) {
  504.     return(binary(args, 'p'));
  505. }
  506.  
  507. int compare_numnodes(NODE *n1, NODE *n2) {
  508.     FLONUM f;
  509.     FIXNUM i;
  510.  
  511.     if (nodetype(n1) == INT) {
  512.    if (nodetype(n2) == INT) {
  513.        i = getint(n1) - getint(n2);
  514.        return (i == 0L ? 0 : (i > 0L ? 1 : -1));
  515.    } else {
  516.        f = (FLONUM)getint(n1) - getfloat(n2);
  517.        return(f == 0.0 ? 0 : (f > 0.0 ? 1 : -1));
  518.    }
  519.     }
  520.     else {
  521.    if (nodetype(n2) == INT) {
  522.        f = getfloat(n1) - (FLONUM)getint(n2);
  523.        return(f == 0.0 ? 0 : (f > 0.0 ? 1 : -1));
  524.    }
  525.    else {
  526.        f = getfloat(n1) - getfloat(n2);
  527.        return(f == 0.0 ? 0 : (f > 0.0 ? 1 : -1));
  528.    }
  529.     }
  530. }
  531.  
  532. NODE *torf(BOOLEAN tf) {
  533.     return (tf ? True : False);
  534. }
  535.  
  536. NODE *llessp(NODE *args) {
  537.     NODE *n1, *n2;
  538.  
  539.     n1 = numeric_arg(args);
  540.     n2 = numeric_arg(cdr(args));
  541.  
  542.     if (NOT_THROWING) {
  543.    return torf(compare_numnodes(n1, n2) < 0);
  544.     }
  545.     return(UNBOUND);
  546. }
  547.  
  548. NODE *lgreaterp(NODE *args) {
  549.     NODE *n1, *n2;
  550.  
  551.     n1 = numeric_arg(args);
  552.     n2 = numeric_arg(cdr(args));
  553.  
  554.     if (NOT_THROWING) {
  555.    return torf(compare_numnodes(n1, n2) > 0);
  556.     }
  557.     return(UNBOUND);
  558. }
  559.  
  560. int compare_node(NODE *n1, NODE *n2, BOOLEAN ignorecase) {
  561.     NODE *a1 = NIL, *a2 = NIL, *nn1 = NIL, *nn2 = NIL;
  562.     int icmp = 0, cmp_len;
  563.     NODETYPES nt1, nt2;
  564.  
  565.     if (n1 == n2) return 0;
  566.  
  567.     nt1 = nodetype(n1);
  568.     nt2 = nodetype(n2);
  569.  
  570.     if (!(nt1 & NT_WORD) || !(nt2 & NT_WORD)) return -9999;
  571.  
  572.     if (nt1 == CASEOBJ && nt2 == CASEOBJ && ignorecase &&
  573.     (object__caseobj(n1) == object__caseobj(n2))) return 0;
  574.  
  575.     if ((nt1 & NT_NUMBER) && (nt2 & NT_NUMBER))
  576.    return compare_numnodes(n1, n2);
  577.  
  578.     if (nt1 & NT_NUMBER) {
  579.    nn2 = cnv_node_to_numnode(n2);
  580.    if (nn2 != UNBOUND) {
  581.        icmp = compare_numnodes(n1, nn2);
  582.        return icmp;
  583.    }
  584.     }
  585.  
  586.     if (nt2 & NT_NUMBER) {
  587.    nn1 = cnv_node_to_numnode(n1);
  588.    if (nn1 != UNBOUND) {
  589.        icmp = compare_numnodes(nn1, n2);
  590.        return icmp;
  591.    }
  592.     }
  593.  
  594.     a1 = cnv_node_to_strnode(n1);
  595.     a2 = cnv_node_to_strnode(n2);
  596.     nt1 = nodetype(a1);
  597.     nt2 = nodetype(a2);
  598.     if (nt1 == STRING && nt2 == STRING) {
  599.    if ((getstrlen(a1) == getstrlen(a2)) &&
  600.           (getstrptr(a1) == getstrptr(a2)))
  601.        icmp = 0;
  602.    else {
  603.    cmp_len = (getstrlen(a1) > getstrlen(a2)) ?
  604.       getstrlen(a2) : getstrlen(a1);
  605.  
  606.    if (ignorecase)
  607.        icmp = low_strncmp(getstrptr(a1), getstrptr(a2), cmp_len);
  608.    else
  609.        icmp = strncmp(getstrptr(a1), getstrptr(a2), cmp_len);
  610.    if ((getstrlen(a1) != getstrlen(a2)) && icmp == 0)
  611.        icmp = getstrlen(a1) - getstrlen(a2);
  612.    }
  613.     }
  614.     else if (nt1 & NT_BACKSL || nt2 & NT_BACKSL) {
  615.    if ((getstrlen(a1) == getstrlen(a2)) &&
  616.          (getstrptr(a1) == getstrptr(a2)))
  617.        icmp = 0;
  618.    else {
  619.    cmp_len = (getstrlen(a1) > getstrlen(a2)) ?
  620.           getstrlen(a2) : getstrlen(a1);
  621.  
  622.    if (ignorecase)
  623.        icmp = noparitylow_strncmp(getstrptr(a1), getstrptr(a2), cmp_len);
  624.    else
  625.        icmp = noparity_strncmp(getstrptr(a1), getstrptr(a2), cmp_len);
  626.    if ((getstrlen(a1) != getstrlen(a2)) && icmp == 0)
  627.        icmp = getstrlen(a1) - getstrlen(a2);
  628.    }
  629.     }
  630.     else err_logo(FATAL, NIL);
  631.  
  632.     return(icmp);
  633. }
  634.  
  635. BOOLEAN equalp_help(NODE *arg1, NODE *arg2, BOOLEAN ignc) {
  636.     if (is_list(arg1)) {
  637.    if (!is_list(arg2)) return FALSE;
  638.    while (arg1 != NIL && arg2 != NIL) {
  639.        if (!equalp_help(car(arg1), car(arg2), ignc))
  640.       return FALSE;
  641.        arg1 = cdr(arg1);
  642.        arg2 = cdr(arg2);
  643.        if (check_throwing) break;
  644.    }
  645.    return (arg1 == NIL && arg2 == NIL);
  646.     } else if (is_list(arg2))
  647.    return FALSE;
  648.     else if (nodetype(arg1) == ARRAY) {
  649.    if (nodetype(arg2) != ARRAY) return FALSE;
  650.    return (arg1 == arg2);
  651.     } else if (nodetype(arg2) == ARRAY)
  652.    return FALSE;
  653.     else return (!compare_node(arg1, arg2, ignc));
  654. }
  655.  
  656. NODE *lequalp(NODE *args) {
  657.     NODE *arg1, *arg2;
  658.     BOOLEAN val;
  659.  
  660.     arg1 = car(args);
  661.     arg2 = cadr(args);
  662.  
  663.     if (compare_node(valnode__caseobj(Caseignoredp), True, TRUE) == 0)
  664.    val = equalp_help(arg1, arg2, TRUE);
  665.     else
  666.    val = equalp_help(arg1, arg2, FALSE);
  667.  
  668.     return(torf(val));
  669. }
  670.  
  671. NODE *l_eq(NODE *args) {
  672.     return torf(car(args) == cadr(args));
  673. }
  674.  
  675. NODE *lbeforep(NODE *args) {
  676.     NODE *arg1, *arg2;
  677.     int val;
  678.  
  679.     arg1 = string_arg(args);
  680.     arg2 = string_arg(cdr(args));
  681.  
  682.     if (compare_node(valnode__caseobj(Caseignoredp), True, TRUE) == 0)
  683.    val = compare_node(arg1, arg2, TRUE);
  684.     else
  685.    val = compare_node(arg1, arg2, FALSE);
  686.  
  687.     return (val < 0 ? True : False);
  688. }
  689.