[alt.sources] Visual calculator "pac", Part 4 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:
# ledit.c onlay.c pac.c pactok.c pipes.c stack.c system.c time.c total.c version.c work.c

echo x - ledit.c
cat > "ledit.c" << '//E*O*F ledit.c//'
/* ledit.c */
/**********************************************************************
*    File Name     : ledit.c
*    Function      : line (window) editor of pac
*    Author        : Istvan Mohos, 1987
***********************************************************************/

#include "defs.h"

ledit(retbuf,Map,line_y,lbound,rbound,video,stripspace,intact)
char *retbuf, *Map;
int line_y, lbound, rbound, video, stripspace, intact;
{
    char c;
    register int ri;
    int rj;
    int lchar, rchar;
    int tbound, bbound;
    int control = 1, retval = 0, first = 1;
    int insert = 0;
    char *rp;
    static char *fid = "ledit";

    _TR

    if (line_y) {
        CY = tbound = bbound = line_y;
        CX = lbound;
    }
    else {
        /* calculator window */
        CY = tbound = UTOP;
        bbound = UBOT;
        CX = ULEFT;
    }
        
    move(CY, CX);
    pfresh();

    while(control) {
        c = fgetc(stdin) & 127;
        if (c == 10 || c == 13)
            break;
        if (c == 17 || c == 19)
            continue;
        if (!intact && first && c > 31) {
            standout();
            mvaddstr(MSG, MSGLEFT, Sp34); /* clear any error messages */
            standend();
            first = 0;
            if (line_y)
                clear_wline(tbound, lbound, rbound, video, 1);
            else
                clear_wline(UTOP, lbound, rbound, video, 3);
        }

        if (video)
            standout();
        switch(*(Map+c)) {

            default:                /* do nothing */
            case 0:
                break;

            case 1:                 /* exit */
                go_away(ZERO, 0);

            case 2:                 /* addch */
                if (insert) {
                    for (rj = bbound; rj >= CY + 1; rj--) {
                        for (ri = rbound; ri >= lbound + 1; ri--)
                            mvaddch(rj, ri, stdscr->_y[rj][ri - 1]);
                        mvaddch(rj, ri, stdscr->_y[rj - 1][rbound]);
                    }
                    for (ri = rbound; ri >= CX + 1; ri--)
                        mvaddch(CY, ri, stdscr->_y[CY][ri - 1]);
                }
                mvaddch(CY,CX,c);
                if(++CX > rbound)
                    if (++CY <= bbound)
                        CX = lbound;
                    else {
                        --CY;
                        --CX;
                    }
                move(CY,CX);
                break;

            case 21:                /* ignore to EOL */
                while((c = fgetc(stdin) & 127) != 10 && c != 13);
                ungetc(c, stdin);
                break;

            case 3:                 /* move left */
                if (--CX < lbound)
                    ++CX;
                move(CY, CX);
                break;

            case 4:                 /* move right */
                if (++CX > rbound)
                    --CX;
                move(CY, CX);
                break;

            case 13:                /* move up */
                if (--CY < tbound)
                    ++CY;
                move(CY, CX);
                break;

            case 14:                /* move down */
                if (++CY > bbound)
                    --CY;
                move(CY, CX);
                break;

            case 15:                /* move down and left */
                if (++CY <= bbound)
                    CX = lbound;
                else
                    --CY;
                move(CY, CX);
                break;

            case 7:                 /* clear; exit */
                clearstack(0);
                Amt = Rate = Years = 0.;
                go_away("I", 0);

            case 8:                 /* wants parent to pop */
                retval = 1;
                control = 0;
                break;

            case 9:                 /* wants parent to push */
                retval = 2;
                control = 0;
                break;

            /* give back last c, read buffer */
            case 12:
                retval = c;
                control = 0;
                break;

            /* give back last c, skip buffer */
            case 17:
                pfresh();
                TR_
                return(c);

            case 10:                /* fill to eol with spaces */
                for (ri = CX; ri <= rbound; ri++)
                    addch(' ');
                for (rj = tbound + 1; rj <= bbound; rj++) {
                    move(rj, lbound);
                    for (ri = CX; ri <= rbound; ri++)
                        addch(' ');
                }
                move(CY,CX);
                break;

            /* curr line: delete char and move 1 pos to left */
            case 11:
                for (ri = CX + 1; ri <= rbound; ri++)
                    addch(stdscr->_y[CY][ri]);
                addch(' ');
                if (--CX < lbound)
                     ++CX;
                move(CY,CX);
                break;

            /* across lines: delete char and move 1 pos to left */
            case 16:
                for (ri = CX + 1; ri <= rbound; ri++)
                    addch(stdscr->_y[CY][ri]);
                for (rj = CY + 1; rj <= bbound; rj++) {
                    addch(stdscr->_y[rj][lbound]);
                    move(rj, lbound);
                    for (ri = lbound + 1; ri <= rbound; ri++)
                        addch(stdscr->_y[rj][ri]);
                }
                addch(' ');
                if (--CX < lbound)
                     ++CX;
                move(CY,CX);
                break;

            case 18 :
                clearok(curscr, TRUE);
                break;                /* ^R redraw */

            case 19 :
                insert = 1;
                break;

            case 20 :
                insert = 0;
                break;
        }
        standend();
        pfresh();
    }

    rp = retbuf; 
    if (stripspace) { /* single line implementation only */
        /* find first non-space from the left */
        for (ri = lbound; ri <= rbound; ri++)
            if ((stdscr->_y[CY][ri] & 127) > 32)
                break;
        if ((lchar = ri) > rbound) {
            *rp = '\0';
            pfresh();
            TR_
            return(retval);
        }
    
        /* find first non-space from the right */
        for (ri = rbound; ri >= lbound; ri--)
            if ((stdscr->_y[CY][ri] & 127) > 32)
                break;
        rchar = ri;
    
        /* give back everything in between */
        for (ri = lchar; ri <= rchar; ri++)
                *rp++ = stdscr->_y[CY][ri] & 127;
    }
    else
        for (rj = tbound; rj <= bbound; rj++)
            for (ri = lbound; ri <= rbound; ri++)
                *rp++ = stdscr->_y[rj][ri] & 127;
    *rp = '\0';
    pfresh();

    if (Trace && Tf != NULL)
        fprintf(Tf, "[%s]\n", retbuf);
    TR_
    return(retval);
}

//E*O*F ledit.c//

echo x - onlay.c
cat > "onlay.c" << '//E*O*F onlay.c//'
/* onlay.c */
/**********************************************************************
*    File Name     : onlay.c
*    Function      : draw initial pac screen
*    Author        : Istvan Mohos, 1987
***********************************************************************/

#define SO standout()
#define SE standend()
#define uw 48
#define re 78
#define se 58
#define sp " "

#include "defs.h"

onlay()
{
    register int i = TOP + 1, j = LBOUND;
    static char *fid = "onlay";

    _TR
 mvaddstr(UTOP,     ATOIX, "^A  asc");
 mvaddstr(UTOP + 1, ATOIX, "^D  dec");
 mvaddstr(UTOP + 2, ATOIX, "^O  oct");
 mvaddstr(UTOP + 3, ATOIX, "^X  hex");

 SO;
 mvaddstr(TOP, j, "  ");
 mvaddstr(TOP, ULEFT, Titlq[0]);
 SE;SO;
 mvaddstr(i,j,sp);mvaddstr(i,uw,sp);mvaddstr(i,se,sp);mvaddstr(i++,re,sp);SE;SO;
 mvaddstr(i,j,sp);mvaddstr(i,uw,sp);mvaddstr(i,se,sp);mvaddstr(i++,re,sp);SE;SO;
 mvaddstr(i,j,sp);mvaddstr(i,uw,sp);mvaddstr(i,se,sp);mvaddstr(i++,re,sp);SE;SO;
 mvaddstr(i,j,sp);mvaddstr(i,uw,sp);mvaddstr(i,se,sp);mvaddstr(i++,re,sp);SE;SO;
 mvaddstr(i,j, "                                               LOAN      ");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);SE;SO;

    SO; mvaddstr(STATY - 1, STATMSG - 1, "    GLOBALS     "); SE;

    i = STACKTOP;
    SO;
    mvaddstr(i,j,"h");SE;addstr("   0");SO;mvaddstr(i,40,"amt");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"i");SE;addstr("   0");SO;mvaddstr(i,40," % ");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"j");SE;addstr("   0");SO;mvaddstr(i,40,"yrs");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"k");SE;addstr("   0");SO;mvaddstr(i,40,"pay");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"l");SE;addstr("   0");SO;mvaddstr(i,40,"^B ");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"m");SE;addstr("   0");SO;mvaddstr(i,40,"   ");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"n");SE;addstr("   0");SO;mvaddstr(i,40,"[le");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"o");SE;addstr("   0");SO;mvaddstr(i,40,"]ri");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"p");SE;addstr("   0");SO;mvaddstr(i,40,"{up");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"q");SE;addstr("   0");SO;mvaddstr(i,40,"}dn");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"r");SE;addstr("   0");SO;mvaddstr(i,40,"|cr");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"s");SE;addstr("   0");SO;mvaddstr(i,40,"^Cl");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"t");SE;addstr("   0");SO;mvaddstr(i,40," BS");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"u");SE;addstr("   0");SO;mvaddstr(i,40,"DEL");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"v");SE;addstr("   0");SO;mvaddstr(i,40,">im");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i,j,"w");SE;addstr("   0");SO;mvaddstr(i,40,"<ei");
        mvaddstr(i,se,sp);mvaddstr(i++,re,sp);
    mvaddstr(i, j, "  ");
    mvaddstr(i, ULEFT, Basq[0]); SE;
TR_
}

update()
{
    register int ri;
    int pyp, pxp;
    static char *fid = "update";

    _TR
    CYX;
    for (ri = TREQ; --ri >= 0;) {
        if (Titlq[ri] != ZERO)  {
            standout();
            mvaddstr(TOP, ULEFT, Titlq[ri]);
            break;
        }
    }

    for (ri = BREQ; --ri >= 0;) {
        if (Basq[ri] != ZERO)  {
            mvaddstr(BOT, ULEFT, Basq[ri]);
            standend();
            break;
        }
    }

    PYX;
TR_
}
//E*O*F onlay.c//

echo x - pac.c
cat > "pac.c" << '//E*O*F pac.c//'
/* pac.c */
/**********************************************************************
*    File Name     : pac.c
*    Object        : pac - 32 digit panel calculator
*    Compile       : makefile, use -DREALUNIX for sysV
*    Author        : Istvan Mohos, 1987
*    Version 1.0   : target completion date Aug 1987
*    Version 1.1   : sysV port, bug-fixes, tuning: Feb 1988
***********************************************************************/

#define MAIN
#include "defs.h"
#undef MAIN
#define PACMAP
#include "maps.h"
#undef PACMAP

extern char *version;

main()
{

    char calbuf[LINEMAX];
    register char *uwcp;
    register int ri;
    int rj, wlen;
    int rc, intact = 0;

#ifdef DEBUG
    if ((Dfp = fopen("debugfile", "w")) == NULL)
        go_away("can't write debugfile", 1);
#endif

    Titlq[0] = Sb[0];
    Basq[0] = Bb[0];
    pipes();
    initscr();

/*  
even though I always strip off the eigth bit of fgetc, it may be a
good idea to set terminal parity to Space */
    raw();
    crmode();
    noecho();
    if (signal(SIGHUP, SIG_IGN) == SIG_DFL)
        signal(SIGHUP, go_away);
    if (signal(SIGINT, SIG_IGN) == SIG_DFL)
        signal(SIGINT, go_away);
    if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
        signal(SIGTERM, go_away);
    if (signal(SIGQUIT, SIG_IGN) == SIG_DFL)
        signal(SIGQUIT, go_away);

    Context = TRUE;   /* go_away() instead of exit() on error */
    onlay();    /* don't need to "update()" */

    if ((Home = getenv("HOME")) == ZERO)
        Rcerr = TRUE;
    else {
        strcpy(Rcfile, Home);
        strcat(Rcfile, "/.pacrc");
    }
    if (!Rcerr) {
        if ((Rcfd = open(Rcfile, 0))  == -1)
            Rcerr = TRUE;
        else {
            read_rc();
            close(Rcfd);
        }
    }
    if (Rcerr) {
        setup_uconv();
        fill_stack(ZERO);
    }

    if (Autotime == ENA) {
        Clockstat = ENA;
        cdate();
    }
    Oldib = Ibase;
    Oldob = Obase;
    show_stack();
    show_uconv();
    show_loan(0);

/* window print field width:
123456789 123456789 123456789 123456789 1234
*/
    sprintf(Mop, "\
pac version: 1.1                            \
last remake: %-*.*s\
author: istvan mohos  0;ib a;pr %d;ob %c;ib %c",
        31,31,version,
        Precision, Base_str[Oldob], Base_str[Oldib]);

    strcpy(Uwin_copy, Mop);
    uwcp = Uwin_copy + strlen(Mop);  /* pad with spaces at end */
    wlen = (UBOT - UTOP) * (URIGHT+1 - ULEFT) - (uwcp - Uwin_copy);
    for (ri = wlen; --ri >= 0; *uwcp++ = ' ');
    *uwcp = '\0';

    interpret(Mop);
    move(CY=UTOP, CX=ULEFT);
    Painted = TRUE;   /* from now on, Mainbuf may be pushed on Stack */

    while (TRUE) {
        if (Clockstat == DISA)
            Titlq[Tqlev] = Sb[Tqlev];
        else
            Titlq[Tqlev] = Cb[Tqlev];

        if (O_conv == FALSE) {
            Basq[CONVREQ] = ZERO;
            update();
        }

        /* ledit starts with pfresh() */
        rc = ledit(calbuf,cal_map,0,ULEFT,URIGHT,0,0,intact);
        intact = 1;

        switch(rc) {

        default:
            break;

#ifdef DESIGN
        case 21 :                /* ^U */
            write_scr("rawscreen", 1);
            break;
        case 25 :                /* ^Y */
            write_scr("pacscreen", 0);
            break;
#endif

        case 1:                  /* ^A: ascii char to dec, hex, oct */
        case 4:                  /* ^D: 3 decimal digits to ... */
        case 15:                 /* ^O: 3 octal digits to ... */
        case 24:                 /* ^X: 2 hex digits to ... */
            byte_conv(rc);
            break;

        case 11 :
            if (Clockstat == DISA) { 
                Clockstat = ENA;
                cdate();
            }
            else {
                Clockstat = DISA;
                clockoff();
                update();
                pfresh();
            }
            break;                /* ^Klock  */

        case 6 :                  /* write to hardcopy */
        case 16 :
            if (Hardcopy == ENA || Hardcopy == AP) {
                Hardcopy = DISA;
                close(Hc);
                Hc = -1;
            }
            else
                (rc == 6) ? (Hardcopy = ENA) : (Hardcopy = AP);
            hard(0);
            break;

        case 12 :
            show_loan(1);
            break;                /* ^L show_loan */

        case 7:                   /* ^Globals */
            if (Statopts)
                show_stat();
            else
                show_param();
            break;

        case 14:                  /* ^N add new conversion */
            newconv();
            break;

        case 20:                  /* ^Total */
            total();
            break;

        case 61:                  /* '=' redo previous window */
            for (uwcp = Uwin_copy, rj = UTOP; rj <= UBOT; rj++)
                for (ri = ULEFT; ri <= URIGHT; ri++)
                    mvaddch(rj, ri, *uwcp++);
            move(CY=UTOP, CX=ULEFT);
            pfresh();
            break;

        case 0:
            intact = 0;
            if (*calbuf == '#') {
                if ( Hc != -1 && Hf != FXTER) {
                    for (uwcp=calbuf+strlen(calbuf); --uwcp > calbuf;)
                        if (*uwcp > 32)
                            break;
                    *++uwcp = '\n';
                    *++uwcp = '\0';
                    ri = strlen(calbuf);
                    if (write(Hc, calbuf, ri) != ri)
                        fatal("comment write");
                }
                break;
            }
            Oldib = Ibase;
            Oldob = Obase;
            strcpy(Uwin_copy, calbuf);
            interpret(calbuf);
            if (Staybase == DISA) {
                Obase = Oldob;
                Ibase = Oldib;
                sprintf(Mop, "ibase=A;obase=%d;ibase=%d\n",
                    Obase, Ibase);
                addto_controlbuf(Mop);
                show_result(0);
            }
            break;
        }
    }
}
//E*O*F pac.c//

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

#include "defs.h"
#define PACTOK
#include "toktab.h"
#undef PACTOK

fill_spreadbuf(buffer)
char *buffer;
{
    register char *bp = buffer;
    register char *spr = Spreadbuf;
    register char prev_c = '\0';
    int first = 0;
    static char *fid = "fill_spreadbuf";

    _TR
    if (*bp == 42 || *bp == 43 || *bp == 45 || *bp == 47 || *bp == 94) {
        *spr++ = '\\';
        *spr++ = ' ';
    }
    while(*bp) {
        if ((ispunct(*bp)    && *bp != '.'    && *bp != '_')   ||
            (ispunct(prev_c) && prev_c != '.' && prev_c != '_'))
            *spr++ = ' ';   /* insert an extra space for pactok */

        if (*bp == ';')
            first = 1;
        else if (first) {
            if (*bp == 42 || *bp == 43 || *bp == 45 ||
                *bp == 47 || *bp == 94) {
                *spr++ = '\\';
                *spr++ = ' ';
                first = 0;
            }
            else if (!isspace(*bp))
                first = 0;
        }

        *spr++ = *bp;
        prev_c = *bp++;
    }
    *spr = '\0';
    if (Hc != -1) {
        *Tmpbuf = '\0';
        if (Hf == FVER) {
            strcpy(Tmpbuf,
"--------------------------------------------");
            spr = Tmpbuf + strlen(Tmpbuf);
            if (Ibase != 10) {
                sprintf(spr, " [ibase: %d]", Ibase);
                spr = Tmpbuf + strlen(Tmpbuf);
            }
            if (Obase != 10) {
                sprintf(spr, " [obase: %d]", Obase);
                spr = Tmpbuf + strlen(Tmpbuf);
            }
            strcat(Tmpbuf, "\n");
        }
        else if (Hf == FTER)
            strcpy(Tmpbuf, "===\n");
    }
    TR_
}

place_pointers()
{
    register int ri, rj;
    register char *cp;
    int thisnum;
    int prevnum;
    static char *fid = "place_pointers";

    _TR
    Tokp[0] = Mainbuf;
    /* take space and comma, unrecognized tokens (digits) will be
       automatically concatenated in Ubuf.
       This permits user formatted input. */

    if ((Tokp[1] = pactok(Spreadbuf, " ,")) == ZERO)
        strcpy(Spreadbuf, "\\");
    else {
        for (cp=Tokp[1], prevnum=1; *cp; cp++) {
            if (! (isdigit(*cp) || (*cp == '.') ||
                   (*cp >= 'a' && *cp <= 'f') ||
                   (*cp >= 'A' && *cp <= 'F'))  ) {
                prevnum = 0;
                break;
            }
        }
        ri = 1;
        while ((Tokp[++ri] = pactok(ZERO, " ,")) != ZERO) {
            for (cp=Tokp[ri], thisnum=1; *cp; cp++) {
                if (! (isdigit(*cp) || (*cp == '.') ||
                       (*cp >= 'a' && *cp <= 'f') ||
                       (*cp >= 'A' && *cp <= 'F'))  ) {
                    thisnum = prevnum = 0;
                    break;
                }
            }
            if (thisnum && prevnum) {
                strcat(Tokp[ri-1], Tokp[ri]);
                --ri;
            }
            if (thisnum)
                prevnum = 1;
        }
        Last = Tokp[ri];       /*  == ZERO */
    }

    if (Hc != -1) {
        if (Hf != FXTER) {
            for (rj = 1; rj < ri;) {
                strcat(Tmpbuf, Tokp[rj++]);
                strcat(Tmpbuf, " ");
            }
            strcat(Tmpbuf, "\n");
            rj = strlen(Tmpbuf);
            if (write(Hc, Tmpbuf, rj) != rj)
                fatal("hardcopy format write");
        }
    }
    TR_
    return(ri); /* # of non-ZERO tokens, including Tokp[0] = Mainbuf */
}

lookup(c_ptr)
char *c_ptr;
{
    int inlist_val;
    static char *fid = "lookup";

    _TR
        if ((inlist_val = spacefill(c_ptr, WORDSIZE)) != -1)
            inlist_val = mybsearch(Tokbuf, toklist, LISTSIZE);
    TR_
    return(inlist_val);
}

char *
pactok(s1, s2)
char *s1, *s2;
{
    register i;
    char *separator[128];
    int sepcount, tok_flag;
    static char *tokenp = ZERO, *parser = ZERO;
    static char *fid = "pactok";

    _TR
    if ((sepcount = strlen(s2)) == 0) {
        TR_
        return(ZERO);
    }
    if (s1 != ZERO)
        tokenp = parser = s1;
    for (i = sepcount; --i >= 0; separator[i] = s2 + i);

    /* move parser, tokenp to first non-separator character */
    while (*parser != '\0') {
        int sep_flag = 0;
        for (i = sepcount; --i >= 0;)
            if (*separator[i] == *parser) {
                ++parser;
                sep_flag = 1;
                break;
            }
        if (!sep_flag)
            break;
    }
    tokenp = parser;
    tok_flag = 0;

    /* move parser to first separator after token, replace value with '\0' */
    while (*parser != '\0') {
        int sep_flag = 0;
        for (i = sepcount; --i >= 0;)
            if (*separator[i] == *parser) {
                *parser++ = '\0';
                sep_flag = 1;
                break;
            }
        if (sep_flag)
            break;
        ++parser;
        tok_flag = 1;
    }

    if (tok_flag) {
        TR_
        return(tokenp);
    }
    TR_
    return(ZERO);
}

mybsearch (comparee, wordlist, listsize)
char *comparee;
char *wordlist[];
{
    register    m, mid, lo, hi;
    static char *fid = "mybsearch";

    _TR
    lo = 0, hi = listsize -1;
    while (lo <= hi) {
        mid = (lo + hi) >> 1;
        if ((m = strcmp(comparee, wordlist[mid])) < 0)
            hi = mid -1;
        else if (m > 0)
            lo = mid +1;
        else {
            TR_
            return(mid);
        }
    }
    TR_
    return (-1);
}
//E*O*F pactok.c//

echo x - pipes.c
cat > "pipes.c" << '//E*O*F pipes.c//'
/* pipes.c */
/**********************************************************************
*    File Name     : pipes.c
*    Function      : make A and B pipes to bc
*    Author        : Istvan Mohos, 1987
***********************************************************************/

#include "defs.h"

pipes()
{
    char tmp[LINEMAX]; /* PLUS6300 needs this --- beats me why */
    /* setup main bc function */
    if (pipe(A_write) == -1 || pipe(A_read) == -1)
        fatal("main pipe setup");
    switch (A_ret = fork()) {
    case -1:
        fatal("main fork");
    case  0:
        if (close(0) == -1 || close(1) == -1)
            fatal("main close1");
        if (dup(A_write[0]) != 0)
            fatal("main dup0");
        if (dup(A_read[1]) != 1)
            fatal("main dup1");
        if (close(A_write[0]) == -1 || close(A_read[0]) == -1 ||
            close(A_write[1]) == -1 || close(A_read[1]) == -1)
            fatal("main close2");
        execlp("/usr/bin/bc", "bc", "-l", 0);
    }
    if (close(A_write[0]) == -1 || close(A_read[1]) == -1)
        fatal("main close3");

    /* setup converter bc function */
    if (pipe(B_write) == -1 || pipe(B_read) == -1)
        fatal("conv pipe setup");
    switch (A_ret = fork()) {
    case -1:
        fatal("conv fork");
    case  0:
        if (close(0) == -1 || close(1) == -1)
            fatal("conv close1");
        if (dup(B_write[0]) != 0)
            fatal("conv dup0");
        if (dup(B_read[1]) != 1)
            fatal("conv dup1");
        if (close(B_write[0]) == -1 || close(B_read[0]) == -1 ||
            close(B_write[1]) == -1 || close(B_read[1]) == -1)
            fatal("conv close2");
        execlp("/usr/bin/bc", "bc", 0);
    }
    if (close(B_write[0]) == -1 || close(B_read[1]) == -1)
        fatal("conv close3");
}

//E*O*F pipes.c//

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

#include "defs.h"

linkup()
{
    register struct stk_cell *sr;
    register int ri;
    static char *fid = "linkup";

    _TR
    sr = &Stk[0];
    for(ri = STACKDEEP+1; --ri; sr++)  /* leave last one dangling */
        sr->link = sr+1;
    TR_
}

fill_stack(from)
char *from;
{
    register struct stk_cell *sr;
    register char *rc = from;
    register int ri;
    static char *fid = "fill_stack";

    _TR
    linkup();

    sr = &Stk[0];                /* accumulator */
    if (from == ZERO) {
        strcpy(sr->cell, Emptycell+2); /* no base char */
        ++sr;
        for (ri = STACKDEEP; --ri >= 0; sr++)
            strcpy(sr->cell, Emptycell);
    }
    else {
        *(rc + STACKMAX) = 0;
        strcpy(sr->cell, Emptycell+2);  /* no base char in accum */
        ++sr;
        for (ri = STACKDEEP; --ri >= 0; sr++) {
            *(rc + STACKMAX) = 0;
            strcpy(sr->cell, rc);
            rc += STACKMAX + 1;
        }
    }
    TR_
}

show_stack()
{
    register struct stk_cell *sr;
    register int ri;
    static char *fid = "show_stack";

    _TR
    sr = Stk[0].link;                /* skip accumulator */
    for (ri = STACKTOP; ri <= STACKBOT; ri++) {
        move(ri, STACKLEFT);
        printw("%s", sr->cell);
        sr = sr->link;
    }
    standout();
    for (ri = STACKTOP; ri <= STACKBOT; ri++) {
        mvaddch(ri, LBOUND, 'h' + ri - STACKTOP);
    }
    standend();
    TR_
}

struct stk_cell *
find(stkpos)
int stkpos;    /* accumulator = 0, h = 1 */
{
    register struct stk_cell *sr;
    register int ri;
    static char *fid = "find";

    _TR
    sr = &Stk[0];
    for (ri = stkpos; --ri >= 0; sr = sr->link);
    TR_
    return(sr);
}

save_stack(to, revstrip)
char *to;
int revstrip;
{
    register struct stk_cell *sr;
    register char *rc = to;
    register int ri;
    static char *fid = "save_stack";

    _TR
    sr = Stk[0].link;                /* skip accumulator */
    for (ri = STACKDEEP; --ri >= 0; sr = sr->link) {
        strcpy(rc, sr->cell);
        rc += STACKMAX;
        if (revstrip) {
            while(*--rc == ' ');
            ++rc;
        }
        *rc++ = '\n';
    }
    *rc = '\0';
    TR_
}

popstack(stkpos)
int stkpos;    /* h = 1 */
{
    register struct stk_cell *sr, *br;
    static char *fid = "popstack";

    _TR
    sr = find(stkpos - 1);
    br = sr->link;
    sr->link = br->link;
    sr = find(STACKDEEP - 1);  /* one is already unlinked */
    sr->link = br;
    strcpy(br->cell, Emptycell);
    show_stack();
    TR_
}

clearstack(stkpos)
int stkpos;
{
    register struct stk_cell *sr;
    static char *fid = "clearstack";

    _TR
    if (stkpos == 0) {
        linkup();
        fill_stack(ZERO);
    }
    else {
        sr = find(stkpos);
        strcpy(sr->cell, Emptycell);
    }
    show_stack();
    TR_
}

pushstack(stkpos)
int stkpos;
{
    register struct stk_cell *sr, *br, *tr;
    static char *fid = "pushstack";

    _TR
    sr = find(stkpos - 1);
    tr = find(STACKDEEP);
    br = sr->link;
    sr->link = tr;
    tr->link = br;
    show_stack();
    TR_
}

onereg(stkpos)
int stkpos;
{
    register struct stk_cell *sr;
    static char *fid = "onereg";

    _TR
    sr = find(stkpos);
    strcpy(Onebuf, sr->cell);
    TR_
}

stack_reg(stkpos, source)
int stkpos, source;
{
    register struct stk_cell *sr, *br;
    static char *fid = "stack_reg";

    _TR
    sr = find(stkpos);
    br = find(source);
    strcpy(sr->cell, br->cell);
    show_stack();
    TR_
}

//E*O*F stack.c//

echo x - system.c
cat > "system.c" << '//E*O*F system.c//'
/* system.c */
/**********************************************************************
*    File Name     : system.c
*    Function      : clean up prior to pac exit, pipe readers
*    Author        : Istvan Mohos, 1987
***********************************************************************/

#include "defs.h"

go_away(message, die)
char *message;
int die;
{
    static char *fid = "go_away";
    int tput_ok = 1;

    _TR
    signal(SIGINT, SIG_IGN);
    signal(SIGHUP, SIG_IGN);
    signal(SIGTERM, SIG_IGN);
    signal(SIGQUIT, SIG_IGN);

    if (Context != INIT) {
        write_rc();
        clockoff();
        Clockstat = DISA;

        if (message != ZERO && *message == 'I') {
            standend();
            mvaddch(LINES-1, 0, ' ');
            clear();
            pfresh();
            mvcur(0, COLS-1, LINES-1, 0);
            endwin();
        }
        else {
            standend();
            mvaddch(LINES-1, 0, ' ');
            pfresh();
            mvcur(0, COLS-1, LINES-1, 0);
            endwin();
            fprintf(stderr, "\n");
        }
    }

    if (die)
        fprintf(stderr, "%s\n", ierbuf);
    TR_
    exit(die);
}

fatal(msg) /* kill pipes, print error messages and go_away */
char *msg;
{
    extern int errno, sys_nerr;
    extern char *sys_errlist[];

    if (A_ret)
        kill(A_ret, SIGTERM), A_ret = 0;
    if (B_ret)
        kill(B_ret, SIGTERM), B_ret = 0;
    go_away(ierbuf, ierror(msg, 1));
}

int
wait_main_pipe() /* empty main pipe to prevent deadlock */
          /* null delimited Mainbuf string may get PIPEMAX long */
{
    register ri;
    register char *accp1, *accp2;
    int done, totalread;
    static char *fid = "wait_main_pipe";

    _TR
    accp1 = Mainbuf;
    done = FALSE;
    totalread = 0;
    while (!done) {
        switch
           (Nread = read(A_read[0], accp1, PIPEMAX)) {
        case -1:
            fatal("wait main read");
        case  0:
            fatal("main bc: mysterious end of file");
        default:
            if ((totalread += Nread) >= PIPEMAX - 80)
                     fatal("main pipe overflow");
            accp2 = accp1;
            for (ri = Nread; --ri >= 0;) {
                if(*accp2 == '\n' && *(accp2 -1) != '\\') {
                    *(accp2) = '\0';
                    --totalread;
                    done = TRUE;
                    break;
                }
                ++accp2;
            }
            if (!done)
                accp1 = accp2;
            break;
        }
    }
    TR_
}

/* empty conv pipe into buf, to prevent deadlock.
   if  non-ZERO, buf size must not be less than PIPEMAX.
   if ZERO, Convbuf is used.  Null byte added at end of buf
*/
wait_conv_pipe(buf)
char *buf;
{
    register ri;
    register char *convp1, *convp2;
    int done, totalread;
    static char *fid = "wait_conv_pipe";

    _TR
    if (buf == ZERO)
        convp1 = Convbuf;
    else
        convp1 = buf;
    done = FALSE;
    totalread = 0;
    while (!done) {
        switch
           (Convread = read(B_read[0], convp1, PIPEMAX)) {
        case -1:
            fatal("wait conv read");
        case  0:
            fatal("conv: mysterious end of file");
        default:
            if ((totalread += Convread) >= PIPEMAX - 80)
                     fatal("conv pipe overflow");
            convp2 = convp1;
            for (ri = Convread; --ri >= 0;) {
                if(*convp2 == '\n' && *(convp2 -1) != '\\') {
                    *(convp2) = '\0';
                    --totalread;
                    done = TRUE;
                    break;
                }
                ++convp2;
            }
            if (!done)
                convp1 = convp2;
            break;
        }
    }
    TR_
}
//E*O*F system.c//

echo x - time.c
cat > "time.c" << '//E*O*F time.c//'
/* time.c */
/**********************************************************************
*    File Name     : time.c
*    Author        : Istvan Mohos, 1987
***********************************************************************/


#ifdef pyr
#include <sys/time.h>
#else
#include <time.h>
#endif

#ifndef LOCALTEST
#include "defs.h"
#else
unsigned alarm();
int cdate();        /* signal has to know */
#include <stdio.h>
#include <signal.h>
char *Thisyear;
main()
{
    year();
    printf("%s<<\n", Thisyear);
    printf("%d", whichmonth("MAY"));
    cdate();
    for (;;);
}
#endif

#ifndef BADSIG
#define BADSIG        (int (*)())-1
#endif

cdate()
{
    long clock;
    int hour;
    register char *d;
    char ptr[30];
    int savy, savx, se;
    static char *fid = "cdate";

    _TR
    clock = time((long *) 0);    /* seconds since 1970 */
    d = ctime(&clock);
    strcpy(ptr, d);

    d = ptr + 8;
    if (*d == ' ') {
        *d = *(d+1);
        *++d = ' ';
    }
    d = ptr + 11;
    if (*d == '0')
        *d = ' ';
    if ((hour = atoi(d)) > 11) {    /* PM */
        if (hour > 12)
            sprintf(d, "%2d", hour -12);
        d+=2;
        *d = ':';
        d+=3;
        *d++ = '.';
    }
    else {
        d = ptr + 16;
        *d++ = ' ';
    }
    *d = '\0';  /* delete :seconds, year, newline */

#ifdef LOCALTEST
    printf("    01234567890123456789012\n>>>>%s<<<<\n", ptr);
    alarm(10);
    if (signal(SIGALRM, cdate) == BADSIG)
         exit(1);
#else
    getyx(stdscr, savy, savx);
    se = (stdscr->_y[stdscr->_cury][stdscr->_curx] < 128);
    if (se)
        standout();
    mvaddstr(TOP,  CONVLEFT, ptr);
    if (se)
        standend();
    move(savy, savx);
    refresh();
    alarm(10);
    if (signal(SIGALRM, cdate) == BADSIG)
         fatal("clock signal");
    TR_
}

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

    _TR
    alarm(0);
    if (signal(SIGALRM, SIG_DFL) == BADSIG)
         fatal("clock signal at off");
    TR_
}

pfresh()
{
    static char *fid = "pfresh";
    _TR
    if (Clockstat == DISA)
        refresh();
    else {
        clockoff();
        refresh();
        cdate();
    }
#endif

    TR_
}

year()
{
    long clock;
    static char ptr[30];
    static char *fid = "year";

    _TR
    clock = time((long *) 0);
    strcpy(ptr, ctime(&clock));

    Thisyear = ptr + 20;
    *(ptr + 24) = '\0'; /* kill newline */
    TR_
}

whichmonth(ptr)
char *ptr;
{
    register int hv = 0;
    register char *hp;

    static char hashbuf[] = {
      12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0,
       3, 0, 0, 4, 0, 0,10, 5, 9, 0, 0, 7, 0, 6, 0, 0, 0, 0, 0,11, };
    static char *fid = "whichmonth";

    _TR
    hp = ptr;
    if (hp == ZERO) {
        TR_
        return(0);
    }
    if (isalpha(*hp)) {
        hv += (*hp++ & 95);
        if (*hp) {
            hv += (*hp++ & 95);
            if (*hp)
                hv += (*hp & 95);
        }
        hv -= 204;
        if (hv < 0 || hv > 39) {
            TR_
            return(0);
    }
        return(hashbuf[hv]);
    }
    if ((hv = atoi(hp)) > 12 || hv < 1) {
        TR_
        return(0);
    }
    TR_
    return(hv);
}
//E*O*F time.c//

echo x - total.c
cat > "total.c" << '//E*O*F total.c//'
/* total.c */
/**********************************************************************
*    File Name     : total.c
*    Function      : pac checkbook balancer (totalizer)
*    Author        : Istvan Mohos, 1987
***********************************************************************/

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

static double Su[FITCONV - 2];
static double Total;

total()
{
    int pyp, pxp;
    char curr_l[CONVMAX + 1];
    register int ri, rj;
    static int f_id = 0;
    int where, ck, copy;
    static char *fid = "total";
    
    _TR
    CYX;
    Tqlev = TALYREQ;
    if (Clockstat == DISA)
        Titlq[TALYREQ] = Sb[TALYREQ];
    else
        Titlq[TALYREQ] = Cb[TALYREQ];
    Basq[TALYREQ] = Bb[TALYREQ];
    standout();
    for (ri = FITCONV - 2, rj = 115; --ri >= 0; rj--)
        mvaddch(UTOP + ri, RBOUND, rj);
    mvaddch(TOP + FITCONV, RBOUND, 't');
    standend();
    clear_wline(TOP+FITCONV-1, CONVLEFT, RBOUND-2, 0, 1);
    show_items();
    show_total(0);
    update();
 
    while(1) {
    
        where = UTOP + f_id;
        if (Su[f_id] == 0.)
            clear_wline(where, CONVLEFT, RBOUND-2, 0, 1);
    

        ck = ledit(curr_l, tot_map, where, CONVLEFT, RBOUND-2, 0, 1, 1);
    
        if (!*curr_l)
            strcpy(curr_l, "0.0");

        switch(ck) {
            case 6:  /* wants to write file */
            case 16:
                if (Totcopy == ENA || Totcopy == AP) {
                    show_total(1);
                    Totcopy = DISA;
                    close(Tc);
                    Tc = -1;
                }
                else {
                    show_total(0);
                    (ck == 6) ? (Totcopy = ENA) : (Totcopy = AP);
                }
                hard(1);
                break;

            case 0:  /* normal return, did read line */
                show_line(f_id, curr_l);
                if (++f_id > FITCONV -3) {
                    show_total(1);
                    f_id = 1;
                    for (ri = FITCONV - 2; --ri > 0; Su[ri] = 0.);
                    Su[0] = Total;
                    show_items();
                }
                show_total(0);
                break;

            case 'T':
                show_line(f_id, curr_l);
                show_total(1);
                break;

            case 1:
                show_line(f_id, curr_l);
                show_total(ck);
                PYX;
                Basq[TALYREQ] = ZERO;
                update();
                pfresh();
                TR_
                return;

            case 3:   /* control-c, clear entire window */
                f_id = 0;
                for (ri = FITCONV - 2; --ri >= 0; Su[ri] = 0.);
                show_items();
                show_total(0);
                break;

            default:
                if (ck > 64 && ck < 84) {   /* A through S */
                    show_line(f_id, curr_l);
                    show_total(0);
                    f_id = ck - 'A';
                }
                else {
                    if ((copy = ck - 97) < FITCONV - 2) /* a to s */
                        sprintf(curr_l, "%*.*f", CONVMAX, Precision,
                            Su[copy]);
                    else /* t */
                        sprintf(curr_l, "%*.*f", CONVMAX, Precision,
                            Total);
                    show_line(f_id, curr_l);
                    if (++f_id > FITCONV -3) {
                        show_total(1);
                        f_id = 1;
                        for (ri = FITCONV - 2; --ri > 0; Su[ri] = 0.);
                        Su[0] = Total;
                        show_items();
                    }
                    show_total(0);
                }
                break;
        }
    }
}

show_total(transfer)
int transfer;
{
    char floatbuf[WINLINE];
    char hardbuf[WINLINE];
    register char *fb = floatbuf;
    register int rx;
    register int ri;
    struct  stk_cell *sr;
    static char *fid = "show_total";
    
    _TR
    Total = 0.;
    for (ri = FITCONV - 2; --ri >= 0; Total += Su[ri]);
    sprintf(fb, "%*.*f", CONVMAX, Precision, Total);
    if ((ri = strlen(floatbuf)) <= CONVMAX) {
        *(fb = floatbuf + ri++) = '.';
        *++fb = 0;
    }
    for (fb = floatbuf + ri; --fb >= floatbuf;)
        if (*fb == '.')
            break;
    if (fb < floatbuf)  {
        Total = 0.;
        sprintf(floatbuf, "%*.*f", CONVMAX, Precision, Total);
    }
    *((fb = floatbuf) + CONVMAX) = 0;
    mvaddstr(TOP + FITCONV, CONVLEFT, fb);
    if (transfer) {
        if (Tc != -1) {
            if (Hf != FXTER) {
                if ((write(Tc, "\n", 1)) != 1)
                    fatal("total write");
                for (ri = UTOP; ri < UTOP + FITCONV - 2; ri++) {
                    fb = hardbuf;
                    *fb++ = ri + 'a' - UTOP;
                    *fb++ = ' ';
                    *fb++ = ' ';
                    *fb++ = ' ';
                    for (rx = CONVLEFT; rx < RBOUND -1; rx++)
                        *fb++ = stdscr->_y[ri][rx] & 127;
                    *fb = '\n';
                    if ((write(Tc, hardbuf, 4+CONVMAX+1))
                        != 4+CONVMAX+1)
                        fatal("total 2 write");
                }
                if ((write(Tc,"    -----------------\nt   ", 26)) != 26)
                    fatal("total 3 write");
                if ((write(Tc, floatbuf, CONVMAX)) != CONVMAX)
                    fatal("total 4 write");
                if ((write(Tc, "\n\n", 2)) != 2)
                    fatal("total 5 write");
            }
            else {
                if ((write(Tc, floatbuf, CONVMAX)) != CONVMAX)
                    fatal("total 6 write");
                if ((write(Tc, "\n", 1)) != 1)
                    fatal("total 7 write");
            }
        }
        if (Stack == ENA)
            pushstack(1);
        /* strip trailing zeros */
        for (fb = floatbuf + strlen(floatbuf); --fb >= floatbuf;)
            if (*fb == '.')
                break;
        if (fb >= floatbuf) {
            for (fb += strlen(fb); *--fb == '0'; *fb = 0);
            if (*fb == '.')
                *fb = 0;
        }
        /* strip preceding spaces */
        for (fb = floatbuf; *fb == ' '; fb++);

        sr = find(1);
        sprintf(sr->cell, "%c %-*.*s", *(Base_str + 10),
            STACKMAX-2, STACKMAX-2, fb);
        show_stack();
    }
    TR_
}

show_line(f_id, buf)
int f_id;
char *buf;
{
    char floatbuf[WINLINE];
    char transbuf[WINLINE];
    register char *fb;
    register char *T = transbuf;
    char *secp;
    double thisval;
    double first = 0., second;
    int where, ri, oper = 0;
    static char *fid = "show_line";
    
    _TR
    where = UTOP + f_id;

    /* strip embedded spaces */
    fb = buf;
    while (*fb) {
        switch(*fb) {
            case ' ':
                break;
            case '*':
            case '@':
                *T++ = 0;
                secp = T;
                oper = 1;
                break;
            case '+':
                *T++ = 0;
                secp = T;
                oper = 2;
                break;
            default:
                *T++ = *fb;
                break;
        }
        fb++;
    }
    *T = 0;
    switch(oper) {
        case 0:
        default:
            thisval = atof(transbuf);
            break;
        case 1:
            if (*transbuf) 
                thisval = first = atof(transbuf);
            if (*secp) {
                second = atof(secp);
                thisval = first * second;
            }
            break;
        case 2:
            if (*transbuf) 
                thisval = first = atof(transbuf);
            if (*secp) {
                second = atof(secp);
                if (second != 0.)
                    thisval = first + second;
            }
            break;
    }
    Su[f_id] = thisval;
    sprintf(floatbuf, "%*.*f", CONVMAX, Precision, thisval);
    if ((ri = strlen(floatbuf)) <= CONVMAX) {
        *(fb = floatbuf + ri++) = '.';
        *++fb = 0;
    }
    for (fb = floatbuf + ri; --fb >= floatbuf;)
        if (*fb == '.')
            break;
    if (fb < floatbuf)  {
        Su[f_id] = 0.;
        sprintf(floatbuf, "%*.*f", CONVMAX, Precision, Su[f_id]);
    }
    *((fb = floatbuf) + CONVMAX) = 0;
    mvaddstr(where, CONVLEFT, floatbuf);
    TR_
}

show_items()
{
    char floatbuf[WINLINE];
    char *fb = floatbuf;
    register int ri;
    static char *fid = "show_items";

    _TR
    for (ri = FITCONV - 2; --ri >= 0;) {
        sprintf(fb, "%*.*f", CONVMAX, Precision, Su[ri]);
        *(fb + CONVMAX) = 0;
        mvaddstr(UTOP + ri, CONVLEFT, fb);
    }
    TR_
}
//E*O*F total.c//

echo x - version.c
cat > "version.c" << '//E*O*F version.c//'
char *version = "Tue Nov 15 17:44:59 EST 1988";
//E*O*F version.c//

echo x - work.c
cat > "work.c" << '//E*O*F work.c//'
/* work.c */
/**********************************************************************
*    File Name     : work.c
*    Function      : general pac subroutines
*    Author        : Istvan Mohos, 1987
***********************************************************************/

#include "defs.h"

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

    _TR
    mvaddstr(ACCUM,ULEFT,Sp44);
    TR_
}

/* pointer should sit on a null byte, as given by things like
   "buf + sizeof(buf)", fill backwards with spaces
   including the next null byte found. */
rev_clear(ptr)
char *ptr;
{
    register char *rp;
    static char *fid = "rev_clear";

    _TR
    for (rp = ptr;;)
        if (*--rp == '\0') {
            *rp = ' ';
             break;
        }
        else
             *rp = ' ';
    TR_
}

clear_wline(ver, lbound, rbound, video, lines)
int ver, lbound, rbound, video, lines;
{
    register ri, rj;
    static char *fid = "clear_wline";

    _TR
    if (!lines)
        lines = 1;
    if (video)
        standout();
    for (rj = ver+lines; --rj >= ver;) {
        move(rj, lbound);
        for (ri = rbound - lbound + 1; --ri >= 0; addch(' '));
    }
    if (video)
        standend();
    move(CY,CX);
    TR_
}

/* spacefills string to max: digit characters, appends '\0'; in Tokbuf.
   returns -1 if string is longer than digit */

spacefill(string, digits)
char *string;
int digits;
{
    register char *reg_c;
    register char r_count;
    static char *fid = "spacefill";

    _TR
    if ((r_count = strlen(string)) > digits) {
        TR_
        return(-1);
    }
    strcpy(Tokbuf, string);
    reg_c = &Tokbuf[r_count];
    while(r_count < digits ) {
        *reg_c++ = ' ';
        ++r_count;
    }
    Tokbuf[digits] = '\0';
    TR_
    return(0);
}

addto_controlbuf(c_ptr)
char *c_ptr;
{
    static char *fid = "addto_controlbuf";

    _TR
    strcat(Controlbuf, "\\\n"); /* prevent oversize input string */
    strcat(Controlbuf, c_ptr);
    TR_
}

addto_ubuf(c_ptr)
char *c_ptr;
{
    static char *fid = "addto_ubuf";

    _TR
    strcat(Ubuf, "\\\n"); /* prevent oversize input string */
    strcat(Ubuf, c_ptr);
    TR_
}

upcase(char_p)
char *char_p;
{
    register char *rcp = char_p;
    static char *fid = "upcase";

    _TR
    do
        if (isalpha(*rcp))
            *rcp &= 95;
    while (*rcp++ != '\0');
    TR_
}

pacinit()
{
    Format    = FORM_DFLT;
    (Format == COMMA_) ? (Separator = ',') : (Separator = ' ');
    Hf        = HF_DFLT;
    Ibase     = IB_DFLT;
    Oldib     = IB_DFLT;
    Obase     = OB_DFLT;
    Oldob     = OB_DFLT;
    Lastob    = OB_DFLT;
    Show      = SHOW_DFLT;
    Justify   = JUS_DFLT;
    Precision = PREC_DFLT;
    Stack     = STACK_DFLT;
    Staybase  = DISA;
    Autoconv  = DISA;
}

int
round(nump, endp)
char *nump, *endp;
{
    register char *fr, *to, *dp;
    int done = 0;
    int dpfound = 0;

    for (fr = nump, dp = endp; --dp >= fr;)
        if (*dp == '.') {
            dpfound = 1;
            break;
        }

    if (!dpfound)
        return(-1);

    fr = endp - 1;
    if (*fr < 53) { /* last digit less than 5 */
        *fr = '\0';
        return(0);
    }

    /* write new values in freed-up byte at right */
    for (to = endp - 1, done = 0; --fr > dp;) {
        if (*fr == '9')
            *to-- = '0';
        else {
            *to-- = *fr + 1;
            done = 1;
            break;
        }
    }

    if (done) { /* left-shift new values back 1 byte */
        for (dp = endp -1; to <= dp;)
            *fr++  = *++to;
        *dp = '\0';
        return(0);
    }

    *to-- = *fr; /* new decimal point */

    for (dp = nump, done = 0; --fr >= dp;) {
        if (*fr == '9')
            *to-- = '0';
        else {
            if (*fr > 47 && *fr < 57) {
                *to-- = *fr + 1;
                done = 1;
                break;
            }
            else {        /* fr got to the left of the first digit */
                *to = '1';
                return(1);
            }
        }
    }

    if (done) { /* left-shift new values back 1 byte */
        for (++to, dp = endp -1; to <= dp;)
            *fr++  = *to++;
        *dp = '\0';
        return(0);
    }

    *dp = '1';
    return(1);

}

//E*O*F work.c//

echo Possible errors detected by \'wc\' [hopefully none]:
temp=/tmp/shar$$
trap "rm -f $temp; exit" 0 1 2 3 15
cat > $temp <<\!!!
     241     738    6967 ledit.c
     106     238    3586 onlay.c
     224     655    6024 pac.c
     224     727    5676 pactok.c
      55     207    1805 pipes.c
     191     490    3746 stack.c
     151     413    3735 system.c
     172     432    3162 time.c
     311     955    8736 total.c
       1       9      48 version.c
     211     587    4228 work.c
    1887    5451   47713 total
!!!
wc  ledit.c onlay.c pac.c pactok.c pipes.c stack.c system.c time.c total.c version.c work.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
====================================================================