[alt.sources] Visual calculator "pac", Part 3 of 4

istvan@hhb.UUCP (Istvan Mohos) (07/14/89)

# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# display.c error.c file.c help.c ierror.c interpret.c

echo x - display.c
cat > "display.c" << '//E*O*F display.c//'
/* display.c */
/**********************************************************************
*    File Name     : display.c
*    Function      : calculator, stack, status window displays of pac
*    Author        : Istvan Mohos, 1987
***********************************************************************/

#include "defs.h"

/* display Mainbuf after wait_main_pipe:
   trim Mainbuf; reformat Mainbuf data in Rebuf, Tmpbuf */
display_accum(showflag)
int showflag;
{
    int zerofill;
    int dp_at = -1;
    register int ri;
    register char *dpptr;
    char *tpt;
    int tmpsiz, readsiz;
    int noint = 0;
    struct stk_cell *sr = &Stk[0];
    static char *fid = "display_accum";

    _TR
    Bc_error = 0;
    Negative = Too_big = Has_dp = FALSE;
    e_syntax();
    e_divby0();
    e_exponent();
    e_bcexec();

    if (*Mainbuf == '-')
        Negative = TRUE;

    dpptr = Mainbuf;
    if (*dpptr == '.') 
        noint = 1;
    ri = 0;
    while (*dpptr != '\0') { /* wait_pipe changed last newline to \0 */
        ++ri;
        if (*dpptr++ == '.') {
            tpt = dpptr + Precision +1;
            *tpt = '\0';  /* cut overenthusiastic bc digits */
            if (tpt == dpptr + strlen(dpptr)) {
                if (round(Mainbuf, Mainbuf+strlen(Mainbuf))) {
                    ++dpptr; /* decimal point shifted 1 byte to right */
                    ++ri;
                }
            }
            Has_dp = TRUE;
            dp_at = ri;
        }
    }
    if (Has_dp) {               /* trailing zero suppression */
        while (*--dpptr == '0') {
            *dpptr = '\0';
            --ri;
        }
        if (*dpptr == '.') {
            if (noint) {
                *dpptr = '0';
                pac_err("underflow");
            }
            else {
                *dpptr = '\0';
                --ri;
            }
            Has_dp = FALSE;
        }
    }
    readsiz = ri;

    if ((strlen(Mainbuf) - Negative - Has_dp) > DIGMAX) {
        Too_big = TRUE;
        if (dp_at >= ACCUMAX)
            Has_dp = FALSE;
        e_overflow();  /* this error leaves oversize number in buffer */
        readsiz = DIGMAX + Negative + Has_dp;
        Mainbuf[readsiz] = '\0';
    }

    sprintf(sr->cell, "%c %-*.*s", *(Base_str + Obase),
        STACKMAX-2, STACKMAX-2, Mainbuf);

    if(Justify == JL) {
        strcpy(Rebuf, Mainbuf);
        strcat(Rebuf, Sp44);
        Rebuf[ACCUMAX] = '\0';
        display(Rebuf);
    }
    else if (Justify == JR) {
        strcpy(Rebuf, Sp44);
        strcpy(&Rebuf[ACCUMAX - readsiz], Mainbuf);
        Rebuf[ACCUMAX] = '\0';
        display(Rebuf);
    }
    else {   /* JF */
        strcpy(Tmpbuf, Mainbuf);
        if (!Too_big) {
            if (Has_dp) {
                strcat(Tmpbuf, Fix32);
                zerofill = Precision - (readsiz - dp_at);
                Tmpbuf[readsiz + zerofill] = '\0';
            }
            else
                sprintf(&Tmpbuf[readsiz], ".%.*s", Precision, Fix32);
        }
        Tmpbuf[DIGMAX + Negative + Has_dp] = '\0';
        tmpsiz = strlen(Tmpbuf);
        strcpy(Rebuf, Sp44);
        strcpy(&Rebuf[ACCUMAX - tmpsiz], Tmpbuf);
        display(Rebuf);
    }

    if ((Stack == ENA) && Painted) {
        pushstack(1);
        stack_reg(1, 0);
    }
    move(CY=UTOP, CX=ULEFT);
    if (showflag)
        pfresh();
    TR_
}

/* break up long digit string with spaces, for formatted display */
display(source)
char *source;
{
    char backward[MYBUF];
    register ri;
    register char *from, *to;
    char *numstart, *frommark, *tomark;
    int inlen, tail, group, int_digs;
    static char *fid = "display";
    
    _TR
    if (Format == DISA) {
        mvaddstr(ACCUM,ULEFT,source);
        if (Hc != -1 && !Hide) {
            if ((write(Hc, source, strlen(source))) !=
                strlen(source))
                fatal("hardcopy accumulator write");
            if ((write(Hc, "\n", 1)) != 1)
                fatal("hardcopy accumulator write");
        }
    }
    else {
        switch(Obase) {
        case 2:
            group = 8;
            break;
        case 8:
        case 10:
            group = 3;
            break;
        case 16:
        default:
            group = 4;
            break;
        }
        inlen = strlen(source);
        from = numstart = source;
        while ((*numstart == ' ') || (*numstart == '-')) {
                ++numstart;
                ++from;
        }
        if (*numstart == '.')
            numstart = ZERO;        /* bc does not prepend 0 before . */

        while (*from != '.' && *from != ' ' && *from != '\0')
            ++from;                 /* stop on dot, space or null */

        if (from == source + inlen)        /* no fraction */
            to = &backward[MYBUF - 1];     /* end of source: '\0' */
        else {
            tail = source - from + inlen;  /* on (include) dec. point */
            to = &backward[MYBUF - 1 - tail - (tail-2)/group];

            frommark = from;
            tomark = to;
            *to++ = *from++;
            for (ri = 0; ++ri < tail;) {
                *to++ = *from++;
                if ((ri % group == 0) && (*from != ' '))
                    *to++ = Separator;
            }
            from = frommark;
            to = tomark;
        }
        backward[MYBUF - 1] = '\0';

        if (numstart != ZERO) {
            --to;
            --from;                        /* back to last int digit */
            int_digs = from - numstart;    /* one more, really */
            for (ri = 0; ++ri <= int_digs;) {
                *to-- = *from--;
                if (ri % group == 0)
                    *to-- = Separator;
            }
            *to = *from;                   /* first integer digit */
        }
        if (Negative)
            *--to = *--from;

        if (Justify == JL) {
            strcpy(Tmpbuf, to);
            strcat(Tmpbuf, Sp44);
            Tmpbuf[ACCUMAX] = '\0';
            mvaddstr(ACCUM,ULEFT, Tmpbuf);
            if (Hc != -1 && !Hide) {
            if ((write(Hc, Tmpbuf, strlen(Tmpbuf))) !=
                strlen(Tmpbuf))
                fatal("hardcopy justified left write");
            if ((write(Hc, "\n", 1)) != 1)
                fatal("hardcopy justified left write");
            }
        }
        else {
            for (ri = from - source + 1; --ri;)
                *to-- = *from--;
            *to = *from;          /* to avoid indexing neg. address */
            to = &backward[MYBUF - 1 - ACCUMAX];
            mvaddstr(ACCUM,ULEFT, to);
            if (Hc != -1 && !Hide) {
                if ((write(Hc, to, strlen(to))) != strlen(to))
                    fatal("justified right write");
                if ((write(Hc, "\n", 1)) != 1)
                    fatal("justified right write");
            }
        }
    }
    TR_
}

/* flag values:
   2)     write to Main pipe, clear_accwin, display_accum.  The user
          input string is assumed to have completed processing.
   1)     write to Main pipe, clear_accwin, display_accum only if
          Show is ENA.  (Some functions may withold the current
          result from the stack, by temporarily disabling Stack.)
          The operation always results in a new value from bc, and
          in the clearing of the input string up to the currently
          scanned token.
   0)     write control info to main pipe, redraw Status window.
          This is a one-way  write to bc, no data is returned in
          the pipe; the accumulator and Lastob contents stay intact.
          Error bar under accum does get cleared.
*/

show_result(flag)
int flag;
{
    int Ubuflen, Controlbuflen;
    static char *fid = "show_result";

    _TR
    if (flag) {
        if ((Ubuflen = strlen(Ubuf)) != 0) {
            if (!(Ubuflen == 2 && Ubuf[0] == ';')) {
                if (Ubuf[Ubuflen - 1] != '\n')
                    Ubuf[Ubuflen++] = '\n';

#ifdef DEBUG
fprintf(Dfp, "Ubuf to A_write: %*.*s<<<\n",Ubuflen, Ubuflen, Ubuf);
#endif

                if (write(A_write[1], Ubuf, Ubuflen) == -1)
                    fatal("ubuf to main pipe write");
                clear_accwin();
                wait_main_pipe();

#ifdef DEBUG
fprintf(Dfp, "Mainbuf read: %s<<<\n", Mainbuf);
#endif

                Lastob = Obase;

                if (Do_conv) {
                    Titlq[TALYREQ] = ZERO;
                    show_uconv();
                    conv_usr();
                }

                if (Show == ENA || flag > 1)
                    display_accum(1);
                else
                    display_accum(0);
            }
            Ubuf[0] = '\0';
        }
    }
    else {
        if ((Controlbuflen = strlen(Controlbuf)) != 0) {
            if (Controlbuf[Controlbuflen - 1] != '\n')
                Controlbuf[Controlbuflen++] = '\n';

#ifdef DEBUG
fprintf(Dfp, "Control to A_write: %*.*s<<<\n", Controlbuflen,
    Controlbuflen, Controlbuf);
#endif

            if (write(A_write[1], Controlbuf, Controlbuflen) == -1)
                fatal("controlbuf to main pipe write");
        }
        show_stat();
        Controlbuf[0] = '\0';
        move(CY=UTOP, CX=ULEFT);
        pfresh();
    }
    TR_
}

show_stat()
{
    static char *statstr = "  23456789ABCDEFX";
    register int cur_y = STATY;
    int pyp, pxp;
    static char *fid = "show_stat";

    _TR
    CYX;
    standout();
    mvaddstr(STATY - 1, STATMSG - 1, "    GLOBALS     ");
    standend();

    move(cur_y++, STATMSG);
    printw("    ibase %c   " , statstr[Ibase]);

    move(cur_y++, STATMSG);
    printw("    obase %c   " , statstr[Obase]);

    mvaddstr(cur_y++, STATMSG, (Staybase == ENA) ?  " staybase on  " 
                                                :  " staybase off " );


    move(cur_y++, STATMSG);
    printw("precision %d  " , Precision);

    mvaddstr(cur_y++, STATMSG, (Autoconv == ENA) ?  " autoconv on  " 
                                                :  " autoconv off " );

    if (Format == COMMA_)
        mvaddstr(cur_y++, STATMSG,  "   format ',' " );
    else if (Format == DISA)
        mvaddstr(cur_y++, STATMSG,  "   format off " );
    else /* SPACE_ */
        mvaddstr(cur_y++, STATMSG,  "   format ' ' " );

    if (Hf == FVER)
        mvaddstr(cur_y++, STATMSG,  " hardform ver " );
    else if (Hf == FTER)
        mvaddstr(cur_y++, STATMSG,  " hardform te  " );
    else
        mvaddstr(cur_y++, STATMSG,  " hardform xt  " );

    if (Justify == JF)
        mvaddstr(cur_y++, STATMSG,  "  justify fix " );
    else if (Justify == JR)
        mvaddstr(cur_y++, STATMSG,  "  justify ri  " );
    else
        mvaddstr(cur_y++, STATMSG,  "  justify le  " );

    mvaddstr(cur_y++, STATMSG, (Stack == ENA) ?  "    stack on  " 
                                             :  "    stack off " );
    mvaddstr(cur_y++, STATMSG, (Autotime == ENA) ?  " autotime on  " 
                                             :  " autotime off " );
    Statopts = 0;

    PYX;
    pfresh();
    TR_
}

show_param()
{
    register int cur_y = STATY;
    int pyp, pxp;
    static char *fid = "show_param";

    _TR
    CYX;
    standout();
    mvaddstr(STATY - 1, STATMSG - 1, " STAT  OPTIONS  ");
    standend();

    mvaddstr(cur_y++, STATMSG, "ib   2 --- 16 ");
    mvaddstr(cur_y++, STATMSG, "ob   2 --- 16 ");
    mvaddstr(cur_y++, STATMSG, "sb     off|on ");
    mvaddstr(cur_y++, STATMSG, "pr   0 --- 32 ");
    mvaddstr(cur_y++, STATMSG, "au     off|on ");
    mvaddstr(cur_y++, STATMSG, "fo  sp|off|cm ");
    mvaddstr(cur_y++, STATMSG, "hf  te|ver|xt ");
    mvaddstr(cur_y++, STATMSG, "ju  le|fix|ri ");
    mvaddstr(cur_y++, STATMSG, "st     off|on ");
    mvaddstr(cur_y++, STATMSG, "at     off|on ");

    Statopts = 1;
    PYX;
    pfresh();
    TR_
}

//E*O*F display.c//

echo x - error.c
cat > "error.c" << '//E*O*F error.c//'
/* error.c */
/**********************************************************************
*    File Name     : error.c
*    Function      : handling of error messages
*    Author        : Istvan Mohos, 1987
***********************************************************************/

#include "defs.h"

e_syntax()
{
    static char *fid = "e_syntax";

    _TR
    if (strncmp(Mainbuf, "syntax error", 12) == 0) {
        if (write(A_write[1], "0\n", 2) == -1)
            fatal("error recovery to main pipe write");
        /* read back a zero, so next error won't hang bc pipe */
        wait_main_pipe();
        standout();
        move(MSG, MSGLEFT);
        printw("bc: syntax error                 ");
        if (Hc != -1 && Hf == FVER)
            if ((write(Hc, "ERROR: syntax\n", 14)) != 14)
                fatal("error recovery hardcopy write");
        standend();
        Bc_error = E_SYNTAX;
    }
TR_
}

e_bcexec()
{
    static char *fid = "e_bcexec";

    _TR
    if (strncmp(Mainbuf, "save:args", 9) == 0) {
        if (write(A_write[1], "0\n", 2) == -1)
            fatal("error recovery to main pipe write");
        /* read back a zero, so next error won't hang bc pipe */
        wait_main_pipe();
        standout();
        move(MSG, MSGLEFT);
        printw("bc: bc calculator failure        ");
        if (Hc != -1 && Hf == FVER)
            if ((write(Hc, "ERROR: bcexec\n", 14)) != 14)
                fatal("error recovery hardcopy write");
        standend();
        Bc_error = E_BCEXEC;
    }
TR_
}

e_divby0()
{
    static char *fid = "e_divby0";

    _TR
    if (strncmp(Mainbuf, "divide by 0", 11) == 0) {
        Mainbuf[0] = '0';
        Mainbuf[1] = '\0';
        standout();
        move(MSG, MSGLEFT);
        printw("bc: divide by 0 error            ");
        if (Hc != -1 && Hf == FVER)
            if ((write(Hc, "ERROR: divide by 0\n", 19)) != 19)
                fatal("divby0 hardcopy write");
        standend();
        Bc_error = E_DIVBY0;
    }
TR_
}

e_exponent()
{
    static char *fid = "e_exponent";

    _TR
    if (strncmp(Mainbuf, "exp not an integer", 18) == 0) {
        Mainbuf[0] = '0';
        Mainbuf[1] = '\0';
        standout();
        move(MSG, MSGLEFT);
        printw("bc: non-integer exponent error   ");
        if (Hc != -1 && Hf == FVER)
            if ((write(Hc, "ERROR: exponent not integer\n", 28)) != 28)
                fatal("non-int exponent hardcopy write");
        standend();
        Bc_error = E_EXPONENT;
    }
    else if (strncmp(Mainbuf, "exp too big", 11) == 0) {
        if (write(A_write[1], "0\n", 2) == -1)
            fatal("exp2big main pipe write");
        /* read back a zero, so next error won't hang bc pipe */
        wait_main_pipe();
        Mainbuf[0] = '0';
        Mainbuf[1] = '\0';
        standout();
        move(MSG, MSGLEFT);
        printw("bc: exponent too big error       ");
        if (Hc != -1 && Hf == FVER)
            if ((write(Hc, "ERROR: exponent too big\n", 24)) !=  24)
                fatal("exp2big hardcopy write");
        standend();
        Bc_error = E_EXPONENT;
    }
TR_
}

e_overflow()
{
    static char *fid = "e_overflow";

    _TR
    if (Has_dp == FALSE) { /* don't really care if some digits beyond
                              the dp fall off, in this case */
        standout();
        move(MSG, MSGLEFT);
        printw(" panel overflow: 32 digits max.  ");
        if (Hc != -1 && Hf == FVER)
            if ((write(Hc, "ERROR: overflow\n", 16)) !=  16)
                fatal("overflow hardcopy write");
        standend();
        Bc_error = E_OVERFLOW;
    }
TR_
}

pac_err(message)
char *message;
{ 
    char msg[35];
    static char *fid = "pac_err";

    _TR
    strcpy(msg, Sp34); 
    if (strlen(message) > 22)
        *(message + 22) = '\0';
    sprintf(msg, "pac error: %-*s", 22, message);
    standout();
    move(MSG, MSGLEFT);
    printw(msg);
    standend();
    pfresh();
TR_
}

//E*O*F error.c//

echo x - file.c
cat > "file.c" << '//E*O*F file.c//'
/* file.c */
/**********************************************************************
*    File Name     : file.c
*    Function      : file i/o of pac: rc, hardcopies, debug files
*    Author        : Istvan Mohos, 1987
***********************************************************************/

#include "defs.h"
#define FILEMAP
#include "maps.h"
#undef FILEMAP

#define RCMIN  (STACKDEEP * (STACKMAX + 1) + 53) /* minimum count */
read_rc()
{
    char rcbuf[PIPEMAX];
    register char *rc = rcbuf;
    static char *fid = "read_rc";

    _TR
    if (read(Rcfd, rc, RCMIN) < RCMIN) {
        mvaddstr(2,4,"Rcerr after RCMIN");
        pfresh();
        Rcerr = TRUE;
        TR_
        return;
    }
    if ((Format = *rc++ -48)!=COMMA_ && Format!=SPACE_ && Format!=DISA)
        Format = FORM_DFLT;
    (Format == COMMA_) ? (Separator = ',') : (Separator = ' ');

    if ((Hf = *rc++ -48) != FVER && Hf != FTER && Hf != FXTER)
        Hf = HF_DFLT;
    if ((Ibase = *rc++ -48) < 2 || Ibase > 16)
        Ibase = IB_DFLT;
    if ((Justify = *rc++ -48) != JL && Justify != JF && Justify != JR)
        Justify = JUS_DFLT;
    if ((Obase = *rc++ -48) < 2 || Obase > 16)
        Obase = OB_DFLT;
    if ((Precision = *rc++ -48) < 0 || Precision > 32)
        Precision = PREC_DFLT;
    if ((Autotime = *rc++ -48) != ENA && Autotime != DISA)
        Autotime = DISA;
    if ((Stack = *rc++ -48) != ENA && Stack != DISA)
        Stack = STACK_DFLT;
    if ((Staybase = *rc++ -48) != ENA && Staybase != DISA)
        Staybase = SB_DFLT;
    if ((Convcount = atoi(rc)) > 255 || Convcount < CONVCOUNT) {
        mvaddstr(2,4,"Rcerr at Convcount");
        pfresh();
        Rcerr = TRUE;
        TR_
        return;
    }
    rc += 4;
    if ((Convsel = atoi(rc)) < 0 || Convsel > Convcount -1)
        Convsel = CONVSEL;
    rc += 4;
    if ((Convhsiz = atoi(rc)) < 1) {
        mvaddstr(2,4,"Rcerr after Convhsiz");
        pfresh();
        Rcerr = TRUE;
        TR_
        return;
    }
    rc += 6;
    if ((Amt = atof(rc)) < 0.)
        Amt = 0.;
    rc += 14;
    if ((Years = atof(rc)) < 0.)
        Years = 0.;
    rc += 8;
    if ((Rate = atof(rc)) < 0.)
        Rate = 0.;
    rc += 8;

    fill_stack(rc);

    if ((Convhom = malloc(Convhsiz)) == ZERO)
        fatal("malloc error at read_rc");

    if (read(Rcfd, Convhom, (int)Convhsiz) != Convhsiz) {
        mvaddstr(2,4,"Rcerr after Convhom");
        pfresh();
        Rcerr = TRUE;
        TR_
        return;
    }

    for (rc = Convhom + Convhsiz; --rc > Convhom;)
        if (*rc == '\n')
            *rc = 0;
 
    realign_conv();
    TR_
}

write_rc()
{
    char rcbuf[PIPEMAX];
    register char *rc = rcbuf;
    static char *fid = "write_rc";

    _TR
    if (Home != ZERO && !Dontsave) {
        if ((Rcfd = open(Rcfile, O_WRONLY | O_CREAT, 0600)) != -1) {

            *rc++ = Format +48;
            *rc++ = Hf +48;
            *rc++ = Ibase +48;
            *rc++ = Justify +48;
            *rc++ = Obase +48;
            *rc++ = Precision +48;
            *rc++ = Autotime +48;
            *rc++ = Stack +48;
            *rc++ = Staybase +48;
            sprintf(rc, "%3d;%3d;%5d\n", Convcount, Convsel, Convhsiz);
            rc += 14;
            sprintf(rc, "%13.2f", Amt);
            rc += 13;
            *rc++ = ';'; /* printf too generous on overflow*/
            sprintf(rc, "%7.3f", Years);
            rc += 7;
            *rc++ = ';';
            sprintf(rc, "%7.3f", Rate);
            rc += 7;
            *rc++ = '\n';

            save_stack(rc, 0);

            if ((write(Rcfd, rcbuf, RCMIN)) != RCMIN)
                fatal("pacrc stack write");

            for (rc = Convhom + Convhsiz; --rc > Convhom;)
                if (*rc == '\0')
                    *rc = '\n';
            if ((write(Rcfd, Convhom, (int)Convhsiz)) != (int)Convhsiz)
                fatal("pacrc conv write");

            close(Rcfd);
       }
    }
    TR_
}

#ifdef DESIGN
read_scr(name)        /* read screen image from named file */
char *name;
{
    FILE *fp;
    register rx, ry;
    static char *fid = "read_scr";

    _TR
    if ((fp = fopen(name, "r")) != NULL) {
        for (ry = 0; ry < LINES; ry++)
            for (rx=0; rx < COLS-1; rx++)
                stdscr->_y[ry][rx] = fgetc(fp);
        fclose(fp);
    }
    TR_
}

write_scr(name, rf)
char *name;
int rf;
{
    FILE *fp;
    register rx, ry;
    static char *fid = "write_scr";

    _TR
    if ((fp = fopen(name, "w")) == NULL)
        Status = 1, fatal("write image");
    if (rf)
        for (ry = 0; ry < LINES; ry++)
            for (rx=0; rx < COLS-1; rx++)
                putc(stdscr->_y[ry][rx] & 0377, fp);
    else
        for (ry = 0; ry < LINES; ry++) {
            for (rx=0; rx < COLS-1; rx++)
                putc(stdscr->_y[ry][rx] & 127, fp);
            putc('\n', fp);
        }
    fclose(fp);
    TR_
}
#endif

hard(fnum)
int fnum;
{
    int newlev;
    int pyp, pxp;
    int *whichfile, *whichfd;
    char *np;
    char *whichname;
    char namebuf[TITSIZ + 1];
    char spaceless[TITSIZ + 1];
    static char *fid = "hard";

    _TR
    if (fnum) {
        whichname = Totname;
        whichfd = &Tc;
        if (*(whichfile = &Totcopy) == ENA)
            newlev = TOTLREQ;
        else if (*whichfile == AP)
            newlev = TAPPREQ;
        else {
            newlev = TALYREQ;
            Basq[TOTLREQ] = ZERO;
            Basq[TAPPREQ] = ZERO;
        }
    }
    else {
        whichname = Hardname;
        whichfd = &Hc;
        if (*(whichfile = &Hardcopy) == ENA)
            newlev = FILEREQ;
        else if (*whichfile == AP)
            newlev = POSTREQ;
        else {
            newlev = 0;
            Basq[FILEREQ] = ZERO;
            Basq[POSTREQ] = ZERO;
        }
    }
    Basq[newlev] = Bb[newlev];
    Basq[EDITREQ] = Bb[newlev];
    CYX;  /* to save the caller's coordinates */
    update();  /* this returns to the original coordinates,
                  but does'nt pfresh */
    
    if (*whichfile == ENA || *whichfile == AP) {

redo:

        ledit(namebuf, f_ed_map, BOT, FBOUND, RBOUND, 1, 1, 0);

        if (strlen(namebuf) == 0) {
            strcpy(spaceless, whichname);
            for (np = spaceless; *np > 32; np++);
            *np = '\0';
            standout();
            mvaddstr(BOT, FBOUND, whichname);
            standend();
            pfresh();
        }
        else {
            strcpy(whichname, namebuf);
            strcpy(spaceless, namebuf);
        }

        if (*whichfile == ENA) {
            if ((*whichfd = open(spaceless,
            O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) {
                standout();
                mvaddstr(BOT, ULEFT, "can't access:");
                standend();
                pfresh();
                goto redo;
            }
        }
        else if ((*whichfd = open(spaceless,
            O_WRONLY | O_APPEND | O_CREAT, 0644)) == -1) {
                standout();
                mvaddstr(BOT, ULEFT, "can't access:");
                standend();
                pfresh();
                goto redo;
        }
        /* make a copy of name in alternate buffer also */
        if (*whichfile == AP) {
            strcpy(Bb[newlev - 1] + BUFSTOP, whichname);
            rev_clear(Bb[newlev - 1] + TITSIZ);
        }
        else {
            strcpy(Bb[newlev + 1] + BUFSTOP, whichname);
            rev_clear(Bb[newlev + 1] + TITSIZ);
        }
        strcpy(Bb[newlev] + BUFSTOP, whichname);
        rev_clear(Bb[newlev] + TITSIZ);
        Basq[EDITREQ] = ZERO;
    }
    PYX;
    update();
    pfresh();
    TR_
}
//E*O*F file.c//

echo x - help.c
cat > "help.c" << '//E*O*F help.c//'
/* help.c */
/**********************************************************************
*    File Name     : help.c
*    Function      : overlay stack window with help list
*    Author        : Istvan Mohos, 1987
***********************************************************************/

#include "defs.h"
#include "toktab.h"

char *hlist[] = {
"!         factorial of n: 2*3*4*...n",
"#         comment from here to EOL  ",
"\'         sum ASCII bytes of nextok ",
";         separator btw. statements ",
"?         abbreviation for help     ",
"X         literal 16                ",
"\\         most recent result        ",
"amass     atomic mass unit, grams   ",
"and       binary bit-wise AND       ",
"arct      a(x) bc arctangent func.  ",
"astro     astronomical unit, km     ",
"at        abbreviation for autotime ",
"atto      * .000 000 000 000 000 001",
"au        abbreviation for autoconv ",
"auto      pac_err: defeat bc keyword",
"autoconv  on/off continuous convert ",
"autotime  turn clock on/off at start",
"avogadro  molecules per gram mole   ",
"boltzmann constant [k] ergs/Kelvin  ",
"break     pac_err: defeat bc keyword",
"bye       exit program; same as TAB ",
"chroma    440 * chroma: Bflat from A",
"clr       clear stack cell nextok   ",
"cm        use comma to format number",
"comma     use comma to format number",
"cos       c(x) bc cosine function   ",
"define    pac_err: defeat bc keyword",
"dontsave  don't write vars to .pacrc",
"dp        same as precision         ",
"ds        abbreviation for dontsave ",
"dup       duplicate stk cell nextok ",
"earthmass mass of earth in kg       ",
"earthrad  radius of earth in meters ",
"echarge   electron charge [e] esu   ",
"emass     electron mass at rest, g  ",
"euler     Euler-Mascheroni constant ",
"exa       *1,000,000,000,000,000,000",
"exit      exit program; same as ^E  ",
"exp       e(x) bc exponential func. ",
"faraday   constant [F] C/kmole      ",
"femto     * .000 000 000 000 001    ",
"fix       show fixed decimal point  ",
"fo        abbreviation for format   ",
"for       pac_err: defeat bc keyword",
"format    commas/spaces in result   ",
"g         acceleration at sea m/s2  ",
"gas       constant [Ro] erg/g mole K",
"giga      * 1,000,000,000           ",
"gravity   constant [G] N m2/kg2     ",
"h         value of stack cell h     ",
"hardform  verbose/terse/xt filedump ",
"heat      mechanical equiv [J] J/cal",
"help      briefly explain next token",
"hf        abbreviation for hardform ",
"i         value of stack cell i     ",
"ib        abbreviation for ibase    ",
"ibase     input radix (2 through 16)",
"if        pac_err: defeat bc keyword",
"init      pac to default parameters ",
"j         value of stack cell j     ",
"ju        abbreviation for justify  ",
"justify   left/right/fix display    ",
"k         value of stack cell k     ",
"kilo      * 1000                    ",
"l         value of stack cell l     ",
"le        abbreviation for left     ",
"left      ju le; print to left side ",
"length    pac_err: defeat bc keyword",
"light     velocity [c] km/s         ",
"lightyear distance covered/year km  ",
"log       l(x) bc log function      ",
"m         value of stack cell m     ",
"mega      * 1,000,000               ",
"micro     * .000 001                ",
"milli     * .001                    ",
"mod       integer mod, unlike bc %  ",
"mohos     clear to nextok, pactrace ",
"moonmass  lunar mass in kg          ",
"moonrad   radius of moon in meters  ",
"n         value of stack cell n     ",
"nano      * .000 000 001            ",
"natural   Naperian log base [e]     ",
"nmass     neutron mass at rest, g   ",
"not       bitwise, field nextok wide",
"o         value of stack cell o     ",
"ob        abbreviation of obase     ",
"obase     output radix (2 thru 16)  ",
"off       disable capability        ",
"on        enable capability         ",
"or        binary, bit-wise OR       ",
"p         value of stack cell p     ",
"parallax  solar, in seconds of arc  ",
"parsec    (parallax + sec2) in km   ",
"pd        percent diff (pdiff)      ",
"pdelta    percent diff (pdiff)      ",
"pdiff     % diff of curtok to nextok",
"pe        percent equal (pequal)    ",
"pequal    curtok% = nextok; total?  ",
"peta      * 1,000,000,000,000,000   ",
"pi        3.1415... (32 hex digits) ",
"pico      * .000 000 000 001        ",
"planck    constant [h] erg sec      ",
"pll       stk cell nextok to curres ",
"pm        percent minus (pminus)    ",
"pmass     proton mass at rest, g    ",
"pminus    subtract nextok percent   ",
"po        percent of (pof)          ",
"pof       what is curtok% of nextok ",
"pop       discard stack cell nextok ",
"pp        percent plus (pplus)      ",
"pplus     add nextok percent        ",
"pr        abbreviation of precision ",
"precision digits used past dp (0-32)",
"psh       curres to stk cell nextok ",
"pv        percent versus (pversus)  ",
"pversus   curtok = 100 %, nextok ? %",
"q         value of stack cell q     ",
"quit      exit program; same as ^E  ",
"r         value of stack cell r     ",
"ri        abbreviation of right     ",
"right     right justify result      ",
"rydberg   constant per meter        ",
"s         value of stack cell s     ",
"sb        abbreviation of staybase  ",
"scale     alias of precision        ",
"sin       s(x) bc sine function     ",
"sound     air speed @ 15 Celsius m/s",
"sp        use space to format number",
"space     use space to format number",
"sqrt      sqrt(x) bc square root    ",
"st        abbreviation of 'stack on'",
"stack     save last 16 results      ",
"staybase  make next radix permanent ",
"stefan    Stefan-Boltzmann J/m2 K4 s",
"sto       store curres in stack cell",
"sunmass   solar mass kg             ",
"sunrad    radius of sun in meters   ",
"swp       swap curres, stack nextok ",
"t         value of stack cell t     ",
"te        abbreviation of terse     ",
"tera      * 1,000,000,000,000       ",
"terse     hardcopy file format      ",
"to        convert curres to nextok  ",
"tomoon    distance from earth, km   ",
"tosun     distance from earth, km   ",
"tw        abbreviation of twoscomp  ",
"twoscomp  bitwise, field nextok wide",
"u         value of stack cell u     ",
"v         value of stack cell v     ",
"ver       abbreviation of verbose   ",
"verbose   hardcopy file format      ",
"w         value of stack cell w     ",
"while     pac_err: defeat bc keyword",
"wien      displacement constant cm K",
"x         the number 16             ",
"xor       curres xor-ed with nextok ",
"xt        abbreviation of xterse    ",
"xterse    hardcopy file format      ",
};

#define HCENTER 6
#define TOFIT   (STACKDEEP - HCENTER)

show_help(cursel)
int cursel;
{
    register ri;
    static int tophelp;
    static char *fid = "show_help";

    _TR
    if (cursel < HCENTER)
        tophelp = 0;
    else if (cursel >= LISTSIZE - TOFIT)
        tophelp = LISTSIZE - STACKDEEP;
    else
        tophelp = cursel - HCENTER + 1;

    for (ri = 0; ri < STACKDEEP; ri++) {
        mvaddstr(ri + STACKTOP, STACKLEFT, hlist[ri + tophelp]);
    }

    standout();
    for (ri = 0; ri < STACKDEEP; ri++) {
        mvaddch(ri + STACKTOP, LBOUND, ' ');
    }
    mvaddstr(STACKTOP + cursel - tophelp, STACKLEFT, hlist[cursel]);
    standend();
TR_
}

//E*O*F help.c//

echo x - ierror.c
cat > "ierror.c" << '//E*O*F ierror.c//'
/* ierror.c */
/**********************************************************************
*    Function      : perror, writes into global string buffer "ierbuf"
*    Author        : Istvan Mohos, 1987
***********************************************************************/

#include <stdio.h>
extern int errno, sys_nerr;
extern char *sys_errlist[];
extern char ierbuf[];

ierror(ustr, badnum)
char *ustr;
int badnum;
{
    register char *cp = NULL;

    if (errno > 0 && errno < sys_nerr) {
        badnum = errno;
        cp = sys_errlist[errno];
    }

    if (ustr != (char *)NULL)
        if (cp != (char *)NULL)
            sprintf(ierbuf, "%s: %s", cp, ustr);
        else
            strcpy(ierbuf, ustr);
    else
        if (cp != (char *)NULL)
            sprintf(ierbuf, "%s:", cp);
        else
            *ierbuf = '\0';

    errno = 0;
    return(badnum);
}
//E*O*F ierror.c//

echo x - interpret.c
cat > "interpret.c" << '//E*O*F interpret.c//'
/* interpret.c */
/**********************************************************************
*    File Name     : interpret.c
*    Function      : pac calculator input tokenizer
*    Author        : Istvan Mohos, 1987
***********************************************************************/

#include "defs.h"
#include "toktab.h"
#define INTERMAP
#include "maps.h"
#undef INTERMAP

#define HIDE_RES Hide = 1; rh = Stack; Stack = DISA; \
                 prec = Precision; Precision = 32; show_result(1); \
                 Hide = 0; Stack = rh; Precision = prec
#define RECOVER  conv_bc(sr->cell, ZERO, 1, 0); addto_ubuf(Convbuf)

interpret(source)
char *source;
{
    char *eye, *nxeye;
    char *ip, itemp[LINEMAX];
    char stacbuf[PIPEMAX];
    int ri, rh, prec;
    int cur_cnt = 0;
    int type, value, nex_type;
    int first;                /* so conversion can refer to Mainbuf */
    int conv_flag;            /* to show that TO has taken place */
    char c_val;
    static char onechar[2];
    static struct stk_cell *sr = &Stk[0];
    static char *fid = "interpret";

    _TR

#ifdef TOX
    static char Tk[100];
    char *tk = &Tk[0];
#endif
            

    /* transfer raw characters from user window to Spreadbuf,
       insert spaces between all but contiguous alphanumeric characters
       to prepare for pactok */
    fill_spreadbuf(source);

    /* strip spaces and commas, null terminate tokens */
    place_pointers();
    *Ubuf = '\0';
    *Controlbuf = '\0';
    first = TRUE;
    conv_flag = FALSE;

    while ((eye = Tokp[++cur_cnt]) != ZERO) {
        type = lookup(eye);

        if ((nxeye = Tokp[cur_cnt + 1]) != ZERO)
            nex_type = lookup(nxeye);
        else
            nex_type = -1;

#ifdef TOX
        sprintf(tk, "%d,", type);
        tk = Tk + strlen(Tk);
#endif

        switch(type) {

        default:
        case NOTINLIST:
            upcase(eye);
            addto_ubuf(eye);
            break;

        case IB:
        case IBASE:
            show_result(1);

            /* ZERO pointer: no more tokens
               Convbuf returned: next token not in preferred list
                   in either case, leave right side alone */

            if ((eye = substivar(-1, Tokp[++cur_cnt], 10))
                == ZERO || eye == Convbuf) {
                --cur_cnt;
                Ibase = IB_DFLT;
            }
            else {
                conv_bc(eye, ZERO, Ibase, 10);
                Ibase = atoi(Convbuf);
                if (Ibase > 16 || Ibase < 2)
                    Ibase = IB_DFLT;
            }
            sprintf(Mop, "ibase=A;ibase=%d\n",Ibase);
            addto_controlbuf(Mop);
            show_result(0);
            break;

        case OB:
        case OBASE:
            show_result(1);
            if ((eye = substivar(-1, Tokp[++cur_cnt], 10))
                == ZERO || eye == Convbuf) {
                --cur_cnt;
                Obase = OB_DFLT;
            }
            else {
                conv_bc(eye, ZERO, Ibase, 10);
                Obase = atoi(Convbuf);
                if (Obase > 16 || Obase < 2)
                    Obase = OB_DFLT;
            }
            sprintf(Mop, "ibase=A;obase=%d;ibase=%d\n", Obase, Ibase);
            addto_controlbuf(Mop);
            show_result(0);
            break;

        case TE:
        case TERSE:
        case VER:
        case VERBOSE:
        case XT:
        case XTERSE:
            show_result(1);
            if (type == TE || type == TERSE)
                Hf = FTER;
            else if (type == VER || type == VERBOSE)
                Hf = FVER;
            else
                Hf = FXTER;
            show_result(0);
            break;

        case FIX:
        case RIGHT:
        case RI:
        case LE:
        case LEFT:
        case CM:
        case COMMA:
        case SP:
        case SPACE:
            show_result(1);
            if (type == FIX)
                Justify = JF;
            else if (type == RIGHT || type == RI)
                Justify = JR;
            else if (type == LE || type == LEFT)
                Justify = JL;
            else if (type == CM || type == COMMA)
                Separator = ',', Format = COMMA_;
            else if (type == SP || type == SPACE)
                Separator = ' ', Format = SPACE_;
            show_result(0);
            break;

        case QUESTION:
        case HELP:
            if (nex_type == -1)
                show_help(HELP);
            else {
                ++cur_cnt;
                show_help(nex_type);
            }
            break;

        case TO:
            if (!first) {
                  HIDE_RES;
            }
            RECOVER;
            eye = Tokp[++cur_cnt];
            if (eye == ZERO)
                --cur_cnt;
            else if ((ri = conv_id(eye)) != -1)
                Convsel = ri;
            else
                --cur_cnt;
            Do_conv = conv_flag = TRUE;
            HIDE_RES;
            show_result(0);
            RECOVER;
            break;

        case AND:
        case OR:
        case XOR:
            if (!first) {
                 HIDE_RES;
            }
            /* resolve left side; convert it to base 2 */
            conv_bc(sr->cell, ZERO, 1, 2);
            strcpy(itemp, Convbuf);

            if ((eye = substivar(-1, Tokp[++cur_cnt], 2))
            == ZERO || eye == Convbuf)
                --cur_cnt, eye = itemp;
            else if (eye == Tokp[cur_cnt]) {
                /* nextok is a digit string */
                conv_bc(eye, ZERO, -1, 2);
                eye = Convbuf;
            }
            if ((ip = bitwise(type, itemp, eye, &ri)) == ZERO) {
                pac_err("conversion range");
                TR_
                return;
            }
            conv_bc(ip, ZERO, 1, 0);
            addto_ubuf(Convbuf);
            HIDE_RES;
            RECOVER;
            break;

        case TW:
        case TWOSCOMP:
        case NOT:
            if (type == TWOSCOMP)
                 type = TW;
            if (!first) {
                 HIDE_RES;
            }
            /* resolve left side; convert it to base 2 */
            conv_bc(sr->cell, ZERO, 1, 2);
            strcpy(itemp, Convbuf);

            if ((eye = substivar(-1, Tokp[++cur_cnt], 10))
            == ZERO || eye == Convbuf) {
                --cur_cnt;
                /* reuse previous result */
                conv_bc(sr->cell, ZERO, 1, 10);
                eye = Convbuf;
            }
            else if (eye == Tokp[cur_cnt]) {
                /* nextok is a digit string */
                conv_bc(eye, ZERO, -1, 10);
                eye = Convbuf;
            }
            if ((ip = bitwise(type, itemp, eye, &ri)) == ZERO) {
                pac_err("conversion range");
                TR_
                return;
            }
            if (ri)
                addto_ubuf("-");
            conv_bc(ip, ZERO, 1, 0);
            addto_ubuf(Convbuf);
            if (type == TW)
                addto_ubuf((ri) ? "-1" : "+1");
            HIDE_RES;
            RECOVER;
            break;

        case MOD:
            if (!first) {
                HIDE_RES;
            }
            ri = Precision;
            sprintf(Mop,"ibase=A;scale=0;ibase=%d\n", Ibase);
            addto_controlbuf(Mop);
            show_result(0);
            conv_bc(sr->cell, ZERO, 1, 0);
            addto_ubuf(Convbuf);
            addto_ubuf("\%");
            if ((eye = substivar(-1, Tokp[++cur_cnt], 0))
                == ZERO || eye == Convbuf) {
                --cur_cnt;
                eye = Convbuf;
            }
            addto_ubuf(eye);
            HIDE_RES;
            sprintf(Mop,"ibase=A;scale=%d;ibase=%d\n",ri, Ibase);
            addto_controlbuf(Mop);
            show_result(0);
            RECOVER;
            break;

        case BANG:
            if (!first) {
                HIDE_RES;
            }
            /* resolve left side; convert it to base 10 */
            conv_bc(sr->cell, ZERO, 1, 10);
            value = atoi(Convbuf);
            if (value < 0)
                 value = 0;
            else if (value > 35)
                 value = 35;
            conv_bc(factab[value], ZERO, 1, 0);
            addto_ubuf(Convbuf);
            HIDE_RES;
            RECOVER;
            break;

        case JUSTIFY:
        case JU:
            eye = Tokp[++cur_cnt];
            if (eye == ZERO) {
                show_result(1);
                Justify = JUS_DFLT;
                show_result(0);
            }
            --cur_cnt;
            break;

        case HF:
        case HARDFORM:
            eye = Tokp[++cur_cnt];
            if (eye == ZERO) {
                show_result(1);
                Hf = HF_DFLT;
                show_result(0);
            }
            --cur_cnt;
            break;

        case SHARP: /* comment start */
            (conv_flag || Autoconv == ENA) ? (O_conv = TRUE)
                                           : (O_conv = FALSE);
            show_result(2);
            TR_
            return;

        case SEMI:
            show_result(1);
            first = 2;
            break;

        case STACK:
        case ST:
        case SB:
        case STAYBASE:
        case AUTOTIME:
        case AT:
            ip = stacbuf;
            ri = 0;
            show_result(1);
            eye = Tokp[++cur_cnt];
            if (eye == ZERO) {
                --cur_cnt;
                if (type == STACK || type == ST)
                    (Stack == ENA) ? (ri = 1) : (Stack = ENA);
                else if (type == STAYBASE || type == SB)
                    Staybase = ENA;
                else if (type == AUTOTIME || type == AT)
                    Autotime = ENA;
                show_result(0);
            }
            else {
                value = lookup(eye);
                if (value == ON)
                    value = ENA;
                else if (value == OFF)
                    value = DISA;
                else {
                    --cur_cnt;
                    value = ENA;
                }
                if (type == STACK || type == ST) {
                    if (value == ENA && Stack == ENA)
                        ri = 1;
                    Stack = value;
                }
                else if (type == STAYBASE || type == SB)
                    Staybase = value;
                else if (type == AUTOTIME || type == AT)
                    Autotime = value;
                show_result(0);
            }
            if (Hc != -1 && ri) {
                save_stack(ip, 1);
                ri = strlen(stacbuf);
                if ((write(Hc, stacbuf, ri)) != ri)
                    fatal("hardcopy stack write");
            }
            break;

        case FORMAT:
        case FO:
            show_result(1);
            eye = Tokp[++cur_cnt];
            if (eye == ZERO) {
                --cur_cnt;
                Format = FORM_DFLT;
                (FORM_DFLT == COMMA_) ? (Separator = '.')
                                     : (Separator = ' ');
            }
            else {
                value = lookup(eye);
                switch (value) {
                    case CM:
                    case COMMA:
                        Separator = ',';
                        Format = COMMA_;
                        break;
                    default:
                        --cur_cnt;
                        Format = FORM_DFLT;
                        (FORM_DFLT == COMMA_) ? (Separator = '.')
                                             : (Separator = ' ');
                        break;
                    case SP:
                    case SPACE:
                        Separator = ' ';
                        Format = SPACE_;
                        break;
                    case OFF:
                        Separator = ' ';
                        Format = DISA;
                        break;
                }
            }
            show_result(0);
            break;

        case PR:
        case PRECISION:
        case SCALE:
        case DP:
            show_result(1);
            /* get right side literal for input */
            if ((eye = substivar(-1, Tokp[++cur_cnt], 10))
                == ZERO || eye == Convbuf) {
                --cur_cnt;
                Precision = PREC_DFLT;
            }
            else {
                Precision = atoi(eye);
                if (Precision < 0  || Precision > 32)
                    Precision = PREC_DFLT;
            }
            sprintf(Mop,"ibase=A;scale=%d;ibase=%d\n",Precision, Ibase);
            addto_controlbuf(Mop);
            show_result(0);
            break;

        case PP: /* PercentPlus */
        case PPLUS:
        case PM: /* PercentMinus */
        case PMINUS:
        case PD: /* PercentDelta */
        case PDELTA:
        case PDIFF:
        case PV: /* PercentVersus */
        case PVERSUS:
        case PO: /* PercentOf */
        case POF:
        case PE: /* PercentEqual */
        case PEQUAL:
            if (!first) {
                HIDE_RES;
            }
            conv_bc(sr->cell, ZERO, 1, 0); /* left side is input */

            /* get right side literal for input */
            if ((eye = substivar(-1, Tokp[++cur_cnt], 0))
                == ZERO || eye == Convbuf) {
                --cur_cnt;
                eye = Convbuf;
            }
            ip = itemp;
            switch (type) {
                case PP:
                case PPLUS:
                    sprintf(ip, "%s+(%s*%s/%s)",
                        Convbuf,Convbuf,eye,hundred[Ibase]);
                    break;
                case PM:
                case PMINUS:
                    sprintf(ip, "%s-(%s*%s/%s)",
                        Convbuf,Convbuf,eye,hundred[Ibase]);
                    break;
                case PV:
                case PVERSUS:
                    sprintf(ip, "%s*%s/%s",
                        eye,hundred[Ibase],Convbuf);
                    break;
                case PD:
                case PDELTA:
                case PDIFF:
                    sprintf(ip, "(%s*(%s-%s))/%s",
                        hundred[Ibase],eye,Convbuf,Convbuf);
                    break;
                case PO:
                case POF:
                    sprintf(ip, "(%s*%s/%s)",
                        eye,Convbuf,hundred[Ibase]);
                    break;
                case PE:
                case PEQUAL:
                    sprintf(ip, "(%s*%s/%s)",
                        eye,hundred[Ibase],Convbuf);
                    break;
            }
            addto_ubuf(ip);
            break;

        case LOG:
            *onechar = *eye;
            addto_ubuf(onechar);
            break;

        case SQRT:
            addto_ubuf(eye);
            break;

        case INIT_:
            show_result(1);
            pacinit();
            sprintf(Mop, "ibase=A;obase=%d;ibase=%d\n", Obase, Ibase);
            addto_controlbuf(Mop);
            show_result(0);
            break;

        case DONTSAVE:
        case DS:
            Dontsave = 1;
            break;

        /* copy accum into chosen stack cell, or onto top of stack.
           Other cells are not disturbed */
        case STO:
            show_result(1);
            if (nxeye == ZERO || strlen(nxeye) > 1 ||
                (strlen(nxeye) == 1 && (*nxeye < 'h' || *nxeye > 'w')))
                c_val = 'h';
            else {
                c_val = *nxeye;
                ++cur_cnt;
            }
            stack_reg(c_val - 'g', 0);
            break;

        case IF:
        case WHILE:
        case FOR:
        case BREAK:
        case DEFINE:
        case LENGTH:
            pac_err("unimplemented key");
            TR_
            return;

        case QUIT:
        case EXIT:
            go_away(ZERO, 0);

        case BYE:
            clearstack(0);
            Amt = Rate = Years = 0.;
            go_away("I", 0);

        /* value = sum of bytes' ascii values of next token are
           substituted (in current Ibase) in input to bc */
        case TICK:
            value = 0;
            if ((eye = Tokp[++cur_cnt]) == ZERO)
                --cur_cnt;
            else
                while (*eye)
                    value += *eye++;
            sprintf(Mop, "%c %d",Base_str[10], value);
            conv_bc(Mop, ZERO, 1, 0);
            addto_ubuf(Convbuf);
            break;

        case BACKSLASH:
            RECOVER;
            break;

        case KILO:
        case ATTO:
        case FEMTO:
        case GIGA:
        case MEGA:
        case MICRO:
        case MILLI:
        case NANO:
        case PICO:
        case TERA:
        case PETA:
        case EXA:
            if (first) {
                RECOVER;
            }
            addto_ubuf("*");
            addto_ubuf(substivar(type, ZERO, Ibase));
            break;

        case X_LOWER:
        case X_UPPER:
            sprintf(itemp, "%s", sixteen[Ibase]);
            addto_ubuf(itemp);
            break;

        /* shift Stack down from named register (or top, if no arg);
           bottom gets lost. Copy accum into named element.
           works independently (in addition to) stack effect */
        case PSH:
            show_result(1);
            if (nxeye == ZERO || strlen(nxeye) > 1 ||
                (strlen(nxeye) == 1 && (*nxeye < 'h' || *nxeye > 'w'))) {
                pushstack(1);
                stack_reg(1, 0);
            }
            else {
                pushstack(*nxeye - 'g');
                stack_reg(*nxeye - 'g', 0);
                ++cur_cnt;
            }
            break;

        /* Move stack element (or top, if no arg) into accum, move up
           all elements below it.  Move 0 into bottom location */
        case PLL:
            show_result(1);
            if (nxeye == ZERO || strlen(nxeye) > 1 ||
                (strlen(nxeye) == 1 && (*nxeye < 'h' || *nxeye > 'w'))) {
                onereg(1);
                popstack(1);
            }
            else {
                onereg(*nxeye - 'g');
                popstack(*nxeye - 'g');
                ++cur_cnt;
            }
            conv_bc(Onebuf, ZERO, 1, 0);
            addto_ubuf(Convbuf);
            HIDE_RES;
            break;

        /* Swap accum and stacktop (no args), or accum and cell (1 arg),
           other registers remain intact */
        case SWP:
            show_result(1);
            if (nxeye == ZERO || strlen(nxeye) > 1 ||
                (strlen(nxeye) == 1 && (*nxeye < 'h' || *nxeye > 'w'))) {
                onereg(1);
                stack_reg(1, 0);
            }
            else {
                onereg(*nxeye - 'g');
                stack_reg(*nxeye - 'g', 0);
                ++cur_cnt;
            }
            conv_bc(Onebuf, ZERO, 1, 0);
            addto_ubuf(Convbuf);
            HIDE_RES;
            break;

        /* Discard top of stack, (no args) or named stack cell (1 arg);
           move up lower locations.  Move 0 into bottom location */
        case POP:
            show_result(1);
            if (nxeye == ZERO || strlen(nxeye) > 1 ||
                (strlen(nxeye) == 1 && (*nxeye < 'h' || *nxeye > 'w')))
                popstack(1);
            else {
                popstack(*nxeye - 'g');
                ++cur_cnt;
            }
            break;

        case MOHOS:
#ifdef TRACE
            if (first) {
                Trace = !Trace;
                if (Trace && Tf == NULL) {
                    Tlev = 18; /* pop 2 off 20 maxdeep tabs */
                    if ((Tf = fopen("pactrace", "w")) == NULL)
                        go_away("bad trace file", 1);
                }
                if (!Trace && Tf != NULL) {
                    fclose(Tf);
                    Tf = NULL;
                }
            }
#endif
            *Ubuf = '\0';
            *Controlbuf = '\0';
            first = TRUE;
            conv_flag = FALSE;
            break;

        case PI:
        case ASTRO:     
        case AMASS:      
        case AVOGADRO:  
        case BOLTZMANN: 
        case ECHARGE:    
        case CHROMA:    
        case EMASS:  
        case EULER:     
        case FARADAY:   
        case G_:        
        case GAS:       
        case GRAVITY:   
        case HEAT:      
        case LIGHT:     
        case LIGHTYEAR: 
        case MOONMASS:     
        case SUNMASS:      
        case EARTHMASS:    
        case NATURAL:   
        case NMASS:   
        case PARSEC:    
        case PARALLAX:    
        case PLANCK:    
        case PMASS:    
        case MOONRAD:     
        case SUNRAD:      
        case EARTHRAD:    
        case RYDBERG:   
        case SOUND:     
        case STEFAN:    
        case TOMOON:    
        case TOSUN:    
        case WIEN:      
            addto_ubuf(substivar(type, ZERO, Ibase));
            break;

        case H_:
        case I_:
        case J_:
        case K_:
        case L_:
        case M_:
        case N_:
        case O_:
        case P_:
        case Q_:
        case R_:
        case S_:
        case T_:
        case U_:
        case V_:
        case W_:
            conv_bc((char *)find(*eye - 'g'), ZERO, 1, 0);
            addto_ubuf(Convbuf);
            break;

        case SIN:
        case COS:
        case EXP:
        case ARCT:
            if (Ibase != 10) {
                pac_err("active in 10 base only");
                TR_
                return;
            }
            *onechar = *eye;
            addto_ubuf(onechar);
            break;

        /* Put 0 into a  specific stack cell, or into
           all cells including accum */
        case CLR:
            if (nxeye == ZERO || strlen(nxeye) > 1 ||
                (strlen(nxeye) == 1 && (*nxeye < 'h' || *nxeye > 'w'))) {
                clearstack(0);
                addto_ubuf(";0;");
            }
            else {
                clearstack(*nxeye - 'g');
                ++cur_cnt;
            }
            show_result(1);
            break;

        /* Values below named cell (or top) move down, bottom gets lost,
           named cell is copied into cell below */
        case DUP:
            show_result(1);
            if (nxeye == ZERO || strlen(nxeye) > 1 ||
                (strlen(nxeye) == 1 && (*nxeye < 'h' || *nxeye > 'w'))) {
                stack_reg('w' - 'g', 0); /* copy it into W first */
                pushstack(1);
            }
            else {
                stack_reg('w' - 'g', *nxeye - 'g');
                pushstack(*nxeye - 'g');
                ++cur_cnt;
            }
            break;

        /* Turn continuous conversion on/off */
        case AU:
        case AUTO:
        case AUTOCONV:
            show_result(1);
            Do_conv = TRUE;
            eye = Tokp[++cur_cnt];
            if (eye == ZERO) {
                --cur_cnt;
                Autoconv = ENA;
                show_result(0);
                break;
            }
            value = lookup(eye);
            if (value != ON && value != OFF) {
                --cur_cnt;
                Autoconv = ENA;
            }
            else if (value == ON)
                Autoconv = ENA;
            else {
                Autoconv = DISA;
                Do_conv = FALSE;
            }
            show_result(0);
            break;

        }
        (first == 2) ? (first = TRUE) : (first = FALSE);
        /* FALSE after evaluating the first token */
    }
    (conv_flag || Autoconv == ENA) ? (O_conv = TRUE) : (O_conv = FALSE);
    show_result(2);

#ifdef TOX
    clear_wline(BOT, ULEFT, RBOUND, 1, 1);
    standout();
    mvaddstr(BOT, ULEFT, Tk);
    standend();
    pfresh();
    sleep(5);
    move(CY, CX);
#endif

    TR_
}

//E*O*F interpret.c//

echo Possible errors detected by \'wc\' [hopefully none]:
temp=/tmp/shar$$
trap "rm -f $temp; exit" 0 1 2 3 15
cat > $temp <<\!!!
     404    1365   11737 display.c
     147     469    3940 error.c
     290     944    7596 file.c
     202    1033    7333 help.c
      36      97     871 ierror.c
     832    2280   23768 interpret.c
    1911    6188   55245 total
!!!
wc  display.c error.c file.c help.c ierror.c interpret.c | sed 's=[^ ]*/==' | diff -b $temp -
exit 0
-- 
        Istvan Mohos
        {ihnp4,decvax,allegra}!philabs!hhb!istvan
        HHB Systems 1000 Wyckoff Ave. Mahwah NJ 07430 201-848-8000
====================================================================