[comp.sources.misc] v14i043: pac - the ultimate UNIX calculator, part 5 of 5

istvan@hhb.UUCP (Istvan Mohos) (08/04/90)

Posting-number: Volume 14, Issue 43
Submitted-by: istvan@hhb.UUCP (Istvan Mohos)
Archive-name: pac/part05

==============================CUT HERE==============================
#!/bin/sh
# This is part 05 of a multipart archive
if touch 2>&1 | fgrep '[-amc]' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= pac.c ==============
echo "x - extracting pac.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > pac.c &&
X/* pac.c */
X/**********************************************************************
X*    File Name     : pac.c
X*    Object        : pac - 32 digit panel calculator
X*    Compile       : makefile, use -DREALUNIX for sysV
X*    Author        : Istvan Mohos, 1987
X*    Version 1.0   : target completion date Aug 1987
X*    Version 1.1   : sysV port, bug-fixes, tuning: Feb 1988
X*    Version 1.2   : various excellent signal/attribute changes from
X*                  :   uunet!auspex!guy (Guy Harris), Jul 19 1989
X*                  : Xenix286 flags by rex!mgse!marks (Mark Seiffert)
X***********************************************************************/
X
X#define MAIN
X#include "defs.h"
X#undef MAIN
X#define PACMAP
X#include "maps.h"
X#undef PACMAP
X
Xextern char *version;
X
Xmain()
X{
X
X    char calbuf[LINEMAX];
X    register char *uwcp;
X    register int ri;
X    int rj, wlen;
X    int rc, intact = 0;
X
X#ifdef DEBUG
X    if ((Dfp = fopen("debugfile", "w")) == NULL)
X        go_away("can't write debugfile", 1);
X#endif
X
X    Titlq[0] = Sb[0];
X    Basq[0] = Bb[0];
X    pipes();
X    initscr();
X
X/*  
Xeven though I always strip off the eigth bit of fgetc, it may be a
Xgood idea to set terminal parity to Space */
X    raw();
X    crmode();
X    noecho();
X    if (signal(SIGHUP, SIG_IGN) == SIG_DFL)
X        signal(SIGHUP, go_away);
X    if (signal(SIGINT, SIG_IGN) == SIG_DFL)
X        signal(SIGINT, go_away);
X    if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
X        signal(SIGTERM, go_away);
X    if (signal(SIGQUIT, SIG_IGN) == SIG_DFL)
X        signal(SIGQUIT, go_away);
X
X    Context = TRUE;   /* go_away() instead of exit() on error */
X    onlay();    /* don't need to "update()" */
X
X    if ((Home = getenv("HOME")) == ZERO)
X        Rcerr = TRUE;
X    else {
X        strcpy(Rcfile, Home);
X        strcat(Rcfile, "/.pacrc");
X    }
X    if (!Rcerr) {
X        if ((Rcfd = open(Rcfile, 0))  == -1)
X            Rcerr = TRUE;
X        else {
X            read_rc();
X            close(Rcfd);
X        }
X    }
X    if (Rcerr) {
X        setup_uconv();
X        fill_stack(ZERO);
X    }
X
X    if (Autotime == ENA) {
X        Clockstat = ENA;
X        cdate();
X    }
X    Oldib = Ibase;
X    Oldob = Obase;
X    show_stack();
X    show_uconv();
X    show_loan(0);
X
X/* window print field width:
X123456789 123456789 123456789 123456789 1234
X*/
X    sprintf(Mop, "\
Xpac version: 1.2                            \
Xlast remake: %-*.*s\
Xauthor: istvan mohos  0;ib a;pr %d;ob %c;ib %c",
X        31,31,version,
X        Precision, Base_str[Oldob], Base_str[Oldib]);
X
X    strcpy(Uwin_copy, Mop);
X    uwcp = Uwin_copy + strlen(Mop);  /* pad with spaces at end */
X    wlen = (UBOT - UTOP) * (URIGHT+1 - ULEFT) - (uwcp - Uwin_copy);
X    for (ri = wlen; --ri >= 0; *uwcp++ = ' ');
X    *uwcp = '\0';
X
X    interpret(Mop);
X    move(CY=UTOP, CX=ULEFT);
X    Painted = TRUE;   /* from now on, Mainbuf may be pushed on Stack */
X
X    while (TRUE) {
X        if (Clockstat == DISA)
X            Titlq[Tqlev] = Sb[Tqlev];
X        else
X            Titlq[Tqlev] = Cb[Tqlev];
X
X        if (O_conv == FALSE) {
X            Basq[CONVREQ] = ZERO;
X            update();
X        }
X
X        /* ledit starts with pfresh() */
X        rc = ledit(calbuf,cal_map,0,ULEFT,URIGHT,0,0,intact);
X        intact = 1;
X
X        switch(rc) {
X
X        default:
X            break;
X
X#ifdef DESIGN
X        case 21 :                /* ^U */
X            write_scr("rawscreen", 1);
X            break;
X        case 25 :                /* ^Y */
X            write_scr("pacscreen", 0);
X            break;
X#endif
X
X        case 1:                  /* ^A: ascii char to dec, hex, oct */
X        case 4:                  /* ^D: 3 decimal digits to ... */
X        case 15:                 /* ^O: 3 octal digits to ... */
X        case 24:                 /* ^X: 2 hex digits to ... */
X            byte_conv(rc);
X            break;
X
X        case 11 :
X            if (Clockstat == DISA) { 
X                Clockstat = ENA;
X                cdate();
X            }
X            else {
X                Clockstat = DISA;
X                clockoff();
X                update();
X                pfresh();
X            }
X            break;                /* ^Klock  */
X
X        case 6 :                  /* write to hardcopy */
X        case 16 :
X            if (Hardcopy == ENA || Hardcopy == AP) {
X                Hardcopy = DISA;
X                close(Hc);
X                Hc = -1;
X            }
X            else
X                (rc == 6) ? (Hardcopy = ENA) : (Hardcopy = AP);
X            hard(0);
X            break;
X
X        case 12 :
X            show_loan(1);
X            break;                /* ^L show_loan */
X
X        case 7:                   /* ^Globals */
X            if (Statopts)
X                show_stat();
X            else
X                show_param();
X            break;
X
X        case 14:                  /* ^N add new conversion */
X            newconv();
X            break;
X
X        case 20:                  /* ^Total */
X            total();
X            break;
X
X        case 61:                  /* '=' redo previous window */
X            for (uwcp = Uwin_copy, rj = UTOP; rj <= UBOT; rj++)
X                for (ri = ULEFT; ri <= URIGHT; ri++)
X                    mvaddch(rj, ri, *uwcp++);
X            move(CY=UTOP, CX=ULEFT);
X            pfresh();
X            break;
X
X        case 0:
X            intact = 0;
X            if (*calbuf == '#') {
X                if ( Hc != -1 && Hf != FXTER) {
X                    for (uwcp=calbuf+strlen(calbuf); --uwcp > calbuf;)
X                        if (*uwcp > 32)
X                            break;
X                    *++uwcp = '\n';
X                    *++uwcp = '\0';
X                    ri = strlen(calbuf);
X                    if (write(Hc, calbuf, ri) != ri)
X                        fatal("comment write");
X                }
X                break;
X            }
X            Oldib = Ibase;
X            Oldob = Obase;
X            strcpy(Uwin_copy, calbuf);
X            interpret(calbuf);
X            if (Staybase == DISA) {
X                Obase = Oldob;
X                Ibase = Oldib;
X                sprintf(Mop, "ibase=A;obase=%d;ibase=%d\n",
X                    Obase, Ibase);
X                addto_controlbuf(Mop);
X                show_result(0);
X            }
X            break;
X        }
X    }
X}
SHAR_EOF
$TOUCH -am 0221163890 pac.c &&
chmod 0644 pac.c ||
echo "restore of pac.c failed"
set `wc -c pac.c`;Wc_c=$1
if test "$Wc_c" != "6229"; then
	echo original size 6229, current size $Wc_c
fi
# ============= pactok.c ==============
echo "x - extracting pactok.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > pactok.c &&
X/* pactok.c */
X/**********************************************************************
X*    File Name     : pactok.c
X*    Function      : pac calculator token recognizer
X*    Author        : Istvan Mohos, 1987
X***********************************************************************/
X
X#include "defs.h"
X#define PACTOK
X#include "toktab.h"
X#undef PACTOK
X
Xfill_spreadbuf(buffer)
Xchar *buffer;
X{
X    register char *bp = buffer;
X    register char *spr = Spreadbuf;
X    register char prev_c = '\0';
X    int first = 0;
X    static char *fid = "fill_spreadbuf";
X
X    _TR
X    if (*bp == 42 || *bp == 43 || *bp == 45 || *bp == 47 || *bp == 94) {
X        *spr++ = '\\';
X        *spr++ = ' ';
X    }
X    while(*bp) {
X        if ((ispunct(*bp)    && *bp != '.'    && *bp != '_')   ||
X            (ispunct(prev_c) && prev_c != '.' && prev_c != '_'))
X            *spr++ = ' ';   /* insert an extra space for pactok */
X
X        if (*bp == ';')
X            first = 1;
X        else if (first) {
X            if (*bp == 42 || *bp == 43 || *bp == 45 ||
X                *bp == 47 || *bp == 94) {
X                *spr++ = '\\';
X                *spr++ = ' ';
X                first = 0;
X            }
X            else if (!isspace(*bp))
X                first = 0;
X        }
X
X        *spr++ = *bp;
X        prev_c = *bp++;
X    }
X    *spr = '\0';
X    if (Hc != -1) {
X        *Tmpbuf = '\0';
X        if (Hf == FVER) {
X            strcpy(Tmpbuf,
X"--------------------------------------------");
X            spr = Tmpbuf + strlen(Tmpbuf);
X            if (Ibase != 10) {
X                sprintf(spr, " [ibase: %d]", Ibase);
X                spr = Tmpbuf + strlen(Tmpbuf);
X            }
X            if (Obase != 10) {
X                sprintf(spr, " [obase: %d]", Obase);
X                spr = Tmpbuf + strlen(Tmpbuf);
X            }
X            strcat(Tmpbuf, "\n");
X        }
X        else if (Hf == FTER)
X            strcpy(Tmpbuf, "===\n");
X    }
X    TR_
X}
X
Xplace_pointers()
X{
X    register int ri, rj;
X    register char *cp;
X    int thisnum;
X    int prevnum;
X    static char *fid = "place_pointers";
X
X    _TR
X    Tokp[0] = Mainbuf;
X    /* take space and comma, unrecognized tokens (digits) will be
X       automatically concatenated in Ubuf.
X       This permits user formatted input. */
X
X    if ((Tokp[1] = pactok(Spreadbuf, " ,")) == ZERO)
X        strcpy(Spreadbuf, "\\");
X    else {
X        for (cp=Tokp[1], prevnum=1; *cp; cp++) {
X            if (! (isdigit(*cp) || (*cp == '.') ||
X                   (*cp >= 'a' && *cp <= 'f') ||
X                   (*cp >= 'A' && *cp <= 'F'))  ) {
X                prevnum = 0;
X                break;
X            }
X        }
X        ri = 1;
X        while ((Tokp[++ri] = pactok(ZERO, " ,")) != ZERO) {
X            for (cp=Tokp[ri], thisnum=1; *cp; cp++) {
X                if (! (isdigit(*cp) || (*cp == '.') ||
X                       (*cp >= 'a' && *cp <= 'f') ||
X                       (*cp >= 'A' && *cp <= 'F'))  ) {
X                    thisnum = prevnum = 0;
X                    break;
X                }
X            }
X            if (thisnum && prevnum) {
X                strcat(Tokp[ri-1], Tokp[ri]);
X                --ri;
X            }
X            if (thisnum)
X                prevnum = 1;
X        }
X        Last = Tokp[ri];       /*  == ZERO */
X    }
X
X    if (Hc != -1) {
X        if (Hf != FXTER) {
X            for (rj = 1; rj < ri;) {
X                strcat(Tmpbuf, Tokp[rj++]);
X                strcat(Tmpbuf, " ");
X            }
X            strcat(Tmpbuf, "\n");
X            rj = strlen(Tmpbuf);
X            if (write(Hc, Tmpbuf, rj) != rj)
X                fatal("hardcopy format write");
X        }
X    }
X    TR_
X    return(ri); /* # of non-ZERO tokens, including Tokp[0] = Mainbuf */
X}
X
Xlookup(c_ptr)
Xchar *c_ptr;
X{
X    int inlist_val;
X    static char *fid = "lookup";
X
X    _TR
X        if ((inlist_val = spacefill(c_ptr, WORDSIZE)) != -1)
X            inlist_val = mybsearch(Tokbuf, toklist, LISTSIZE);
X    TR_
X    return(inlist_val);
X}
X
Xchar *
Xpactok(s1, s2)
Xchar *s1, *s2;
X{
X    register i;
X    char *separator[128];
X    int sepcount, tok_flag;
X    static char *tokenp = ZERO, *parser = ZERO;
X    static char *fid = "pactok";
X
X    _TR
X    if ((sepcount = strlen(s2)) == 0) {
X        TR_
X        return(ZERO);
X    }
X    if (s1 != ZERO)
X        tokenp = parser = s1;
X    for (i = sepcount; --i >= 0; separator[i] = s2 + i);
X
X    /* move parser, tokenp to first non-separator character */
X    while (*parser != '\0') {
X        int sep_flag = 0;
X        for (i = sepcount; --i >= 0;)
X            if (*separator[i] == *parser) {
X                ++parser;
X                sep_flag = 1;
X                break;
X            }
X        if (!sep_flag)
X            break;
X    }
X    tokenp = parser;
X    tok_flag = 0;
X
X    /* move parser to first separator after token, replace value with '\0' */
X    while (*parser != '\0') {
X        int sep_flag = 0;
X        for (i = sepcount; --i >= 0;)
X            if (*separator[i] == *parser) {
X                *parser++ = '\0';
X                sep_flag = 1;
X                break;
X            }
X        if (sep_flag)
X            break;
X        ++parser;
X        tok_flag = 1;
X    }
X
X    if (tok_flag) {
X        TR_
X        return(tokenp);
X    }
X    TR_
X    return(ZERO);
X}
X
Xmybsearch (comparee, wordlist, listsize)
Xchar *comparee;
Xchar *wordlist[];
X{
X    register    m, mid, lo, hi;
X    static char *fid = "mybsearch";
X
X    _TR
X    lo = 0, hi = listsize -1;
X    while (lo <= hi) {
X        mid = (lo + hi) >> 1;
X        if ((m = strcmp(comparee, wordlist[mid])) < 0)
X            hi = mid -1;
X        else if (m > 0)
X            lo = mid +1;
X        else {
X            TR_
X            return(mid);
X        }
X    }
X    TR_
X    return (-1);
X}
SHAR_EOF
$TOUCH -am 0221163890 pactok.c &&
chmod 0644 pactok.c ||
echo "restore of pactok.c failed"
set `wc -c pactok.c`;Wc_c=$1
if test "$Wc_c" != "5676"; then
	echo original size 5676, current size $Wc_c
fi
# ============= pipes.c ==============
echo "x - extracting pipes.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > pipes.c &&
X/* pipes.c */
X/**********************************************************************
X*    File Name     : pipes.c
X*    Function      : make A and B pipes to bc
X*    Author        : Istvan Mohos, 1987
X***********************************************************************/
X
X#include "defs.h"
X
Xpipes()
X{
X    char tmp[LINEMAX]; /* PLUS6300 needs this --- beats me why */
X    /* setup main bc function */
X    if (pipe(A_write) == -1 || pipe(A_read) == -1)
X        fatal("main pipe setup");
X    switch (A_ret = fork()) {
X    case -1:
X        fatal("main fork");
X    case  0:
X        if (close(0) == -1 || close(1) == -1)
X            fatal("main close1");
X        if (dup(A_write[0]) != 0)
X            fatal("main dup0");
X        if (dup(A_read[1]) != 1)
X            fatal("main dup1");
X        if (close(A_write[0]) == -1 || close(A_read[0]) == -1 ||
X            close(A_write[1]) == -1 || close(A_read[1]) == -1)
X            fatal("main close2");
X        execlp("/usr/bin/bc", "bc", "-l", 0);
X    }
X    if (close(A_write[0]) == -1 || close(A_read[1]) == -1)
X        fatal("main close3");
X
X    /* setup converter bc function */
X    if (pipe(B_write) == -1 || pipe(B_read) == -1)
X        fatal("conv pipe setup");
X    switch (A_ret = fork()) {
X    case -1:
X        fatal("conv fork");
X    case  0:
X        if (close(0) == -1 || close(1) == -1)
X            fatal("conv close1");
X        if (dup(B_write[0]) != 0)
X            fatal("conv dup0");
X        if (dup(B_read[1]) != 1)
X            fatal("conv dup1");
X        if (close(B_write[0]) == -1 || close(B_read[0]) == -1 ||
X            close(B_write[1]) == -1 || close(B_read[1]) == -1)
X            fatal("conv close2");
X        execlp("/usr/bin/bc", "bc", 0);
X    }
X    if (close(B_write[0]) == -1 || close(B_read[1]) == -1)
X        fatal("conv close3");
X}
X
SHAR_EOF
$TOUCH -am 0221163890 pipes.c &&
chmod 0644 pipes.c ||
echo "restore of pipes.c failed"
set `wc -c pipes.c`;Wc_c=$1
if test "$Wc_c" != "1805"; then
	echo original size 1805, current size $Wc_c
fi
# ============= stack.c ==============
echo "x - extracting stack.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > stack.c &&
X/* stack.c */
X/**********************************************************************
X*    File Name     : stack.c
X*    Function      : user stack
X*    Author        : Istvan Mohos, 1987
X***********************************************************************/
X
X#include "defs.h"
X
Xlinkup()
X{
X    register struct stk_cell *sr;
X    register int ri;
X    static char *fid = "linkup";
X
X    _TR
X    sr = &Stk[0];
X    for(ri = STACKDEEP+1; --ri; sr++)  /* leave last one dangling */
X        sr->link = sr+1;
X    TR_
X}
X
Xfill_stack(from)
Xchar *from;
X{
X    register struct stk_cell *sr;
X    register char *rc = from;
X    register int ri;
X    static char *fid = "fill_stack";
X
X    _TR
X    linkup();
X
X    sr = &Stk[0];                /* accumulator */
X    if (from == ZERO) {
X        strcpy(sr->cell, Emptycell+2); /* no base char */
X        ++sr;
X        for (ri = STACKDEEP; --ri >= 0; sr++)
X            strcpy(sr->cell, Emptycell);
X    }
X    else {
X        *(rc + STACKMAX) = 0;
X        strcpy(sr->cell, Emptycell+2);  /* no base char in accum */
X        ++sr;
X        for (ri = STACKDEEP; --ri >= 0; sr++) {
X            *(rc + STACKMAX) = 0;
X            strcpy(sr->cell, rc);
X            rc += STACKMAX + 1;
X        }
X    }
X    TR_
X}
X
Xshow_stack()
X{
X    register struct stk_cell *sr;
X    register int ri;
X    static char *fid = "show_stack";
X
X    _TR
X    sr = Stk[0].link;                /* skip accumulator */
X    for (ri = STACKTOP; ri <= STACKBOT; ri++) {
X        move(ri, STACKLEFT);
X        printw("%s", sr->cell);
X        sr = sr->link;
X    }
X    standout();
X    for (ri = STACKTOP; ri <= STACKBOT; ri++) {
X        mvaddch(ri, LBOUND, 'h' + ri - STACKTOP);
X    }
X    standend();
X    TR_
X}
X
Xstruct stk_cell *
Xfind(stkpos)
Xint stkpos;    /* accumulator = 0, h = 1 */
X{
X    register struct stk_cell *sr;
X    register int ri;
X    static char *fid = "find";
X
X    _TR
X    sr = &Stk[0];
X    for (ri = stkpos; --ri >= 0; sr = sr->link);
X    TR_
X    return(sr);
X}
X
Xsave_stack(to, revstrip)
Xchar *to;
Xint revstrip;
X{
X    register struct stk_cell *sr;
X    register char *rc = to;
X    register int ri;
X    static char *fid = "save_stack";
X
X    _TR
X    sr = Stk[0].link;                /* skip accumulator */
X    for (ri = STACKDEEP; --ri >= 0; sr = sr->link) {
X        strcpy(rc, sr->cell);
X        rc += STACKMAX;
X        if (revstrip) {
X            while(*--rc == ' ');
X            ++rc;
X        }
X        *rc++ = '\n';
X    }
X    *rc = '\0';
X    TR_
X}
X
Xpopstack(stkpos)
Xint stkpos;    /* h = 1 */
X{
X    register struct stk_cell *sr, *br;
X    static char *fid = "popstack";
X
X    _TR
X    sr = find(stkpos - 1);
X    br = sr->link;
X    sr->link = br->link;
X    sr = find(STACKDEEP - 1);  /* one is already unlinked */
X    sr->link = br;
X    strcpy(br->cell, Emptycell);
X    show_stack();
X    TR_
X}
X
Xclearstack(stkpos)
Xint stkpos;
X{
X    register struct stk_cell *sr;
X    static char *fid = "clearstack";
X
X    _TR
X    if (stkpos == 0) {
X        linkup();
X        fill_stack(ZERO);
X    }
X    else {
X        sr = find(stkpos);
X        strcpy(sr->cell, Emptycell);
X    }
X    show_stack();
X    TR_
X}
X
Xpushstack(stkpos)
Xint stkpos;
X{
X    register struct stk_cell *sr, *br, *tr;
X    static char *fid = "pushstack";
X
X    _TR
X    sr = find(stkpos - 1);
X    tr = find(STACKDEEP);
X    br = sr->link;
X    sr->link = tr;
X    tr->link = br;
X    show_stack();
X    TR_
X}
X
Xonereg(stkpos)
Xint stkpos;
X{
X    register struct stk_cell *sr;
X    static char *fid = "onereg";
X
X    _TR
X    sr = find(stkpos);
X    strcpy(Onebuf, sr->cell);
X    TR_
X}
X
Xstack_reg(stkpos, source)
Xint stkpos, source;
X{
X    register struct stk_cell *sr, *br;
X    static char *fid = "stack_reg";
X
X    _TR
X    sr = find(stkpos);
X    br = find(source);
X    strcpy(sr->cell, br->cell);
X    show_stack();
X    TR_
X}
X
SHAR_EOF
$TOUCH -am 0221163890 stack.c &&
chmod 0644 stack.c ||
echo "restore of stack.c failed"
set `wc -c stack.c`;Wc_c=$1
if test "$Wc_c" != "3746"; then
	echo original size 3746, current size $Wc_c
fi
# ============= system.c ==============
echo "x - extracting system.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > system.c &&
X/* system.c */
X/**********************************************************************
X*    File Name     : system.c
X*    Function      : clean up prior to pac exit, pipe readers
X*    Author        : Istvan Mohos, 1987
X***********************************************************************/
X
X#include "defs.h"
X
Xgo_away(message, die)
Xchar *message;
Xint die;
X{
X    static char *fid = "go_away";
X    int tput_ok = 1;
X
X    _TR
X    signal(SIGINT, SIG_IGN);
X    signal(SIGHUP, SIG_IGN);
X    signal(SIGTERM, SIG_IGN);
X    signal(SIGQUIT, SIG_IGN);
X
X    if (Context != INIT) {
X        write_rc();
X        clockoff();
X        Clockstat = DISA;
X
X        if (message != ZERO && *message == 'I') {
X            standend();
X            mvaddch(LINES-1, 0, ' ');
X            clear();
X            pfresh();
X            mvcur(0, COLS-1, LINES-1, 0);
X            endwin();
X        }
X        else {
X            standend();
X            mvaddch(LINES-1, 0, ' ');
X            pfresh();
X            mvcur(0, COLS-1, LINES-1, 0);
X            endwin();
X            fprintf(stderr, "\n");
X        }
X    }
X
X    if (die)
X        fprintf(stderr, "%s\n", ierbuf);
X    TR_
X    exit(die);
X}
X
Xfatal(msg) /* kill pipes, print error messages and go_away */
Xchar *msg;
X{
X    extern int errno, sys_nerr;
X    extern char *sys_errlist[];
X
X    if (A_ret)
X        kill(A_ret, SIGTERM), A_ret = 0;
X    if (B_ret)
X        kill(B_ret, SIGTERM), B_ret = 0;
X    go_away(ierbuf, ierror(msg, 1));
X}
X
Xint
Xwait_main_pipe() /* empty main pipe to prevent deadlock */
X          /* null delimited Mainbuf string may get PIPEMAX long */
X{
X    register ri;
X    register char *accp1, *accp2;
X    int done, totalread;
X    static char *fid = "wait_main_pipe";
X
X    _TR
X    accp1 = Mainbuf;
X    done = FALSE;
X    totalread = 0;
X    while (!done) {
X        switch
X           (Nread = read(A_read[0], accp1, PIPEMAX)) {
X        case -1:
X            fatal("wait main read");
X        case  0:
X            fatal("main bc: mysterious end of file");
X        default:
X            if ((totalread += Nread) >= PIPEMAX - 80)
X                     fatal("main pipe overflow");
X            accp2 = accp1;
X            for (ri = Nread; --ri >= 0;) {
X                if(*accp2 == '\n' && *(accp2 -1) != '\\') {
X                    *(accp2) = '\0';
X                    --totalread;
X                    done = TRUE;
X                    break;
X                }
X                ++accp2;
X            }
X            if (!done)
X                accp1 = accp2;
X            break;
X        }
X    }
X    TR_
X}
X
X/* empty conv pipe into buf, to prevent deadlock.
X   if  non-ZERO, buf size must not be less than PIPEMAX.
X   if ZERO, Convbuf is used.  Null byte added at end of buf
X*/
Xwait_conv_pipe(buf)
Xchar *buf;
X{
X    register ri;
X    register char *convp1, *convp2;
X    int done, totalread;
X    static char *fid = "wait_conv_pipe";
X
X    _TR
X    if (buf == ZERO)
X        convp1 = Convbuf;
X    else
X        convp1 = buf;
X    done = FALSE;
X    totalread = 0;
X    while (!done) {
X        switch
X           (Convread = read(B_read[0], convp1, PIPEMAX)) {
X        case -1:
X            fatal("wait conv read");
X        case  0:
X            fatal("conv: mysterious end of file");
X        default:
X            if ((totalread += Convread) >= PIPEMAX - 80)
X                     fatal("conv pipe overflow");
X            convp2 = convp1;
X            for (ri = Convread; --ri >= 0;) {
X                if(*convp2 == '\n' && *(convp2 -1) != '\\') {
X                    *(convp2) = '\0';
X                    --totalread;
X                    done = TRUE;
X                    break;
X                }
X                ++convp2;
X            }
X            if (!done)
X                convp1 = convp2;
X            break;
X        }
X    }
X    TR_
X}
SHAR_EOF
$TOUCH -am 0221163890 system.c &&
chmod 0644 system.c ||
echo "restore of system.c failed"
set `wc -c system.c`;Wc_c=$1
if test "$Wc_c" != "3735"; then
	echo original size 3735, current size $Wc_c
fi
# ============= time.c ==============
echo "x - extracting time.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > time.c &&
X/* time.c */
X/**********************************************************************
X*    File Name     : time.c
X*    Author        : Istvan Mohos, 1987
X***********************************************************************/
X
X
X#ifdef pyr
X#include <sys/time.h>
X#else
X#include <time.h>
X#endif
X
X#ifndef LOCALTEST
X#include "defs.h"
X#else
Xunsigned alarm();
Xint cdate();        /* signal has to know */
X#include <stdio.h>
X#include <signal.h>
Xchar *Thisyear;
Xmain()
X{
X    year();
X    printf("%s<<\n", Thisyear);
X    printf("%d", whichmonth("MAY"));
X    cdate();
X    for (;;);
X}
X#endif
X
X#ifndef BADSIG
X#define BADSIG        (int (*)())-1
X#endif
X
Xcdate()
X{
X    long clock;
X    int hour;
X    register char *d;
X    char ptr[30];
X    int savy, savx, se;
X    static char *fid = "cdate";
X
X    _TR
X    clock = time((long *) 0);    /* seconds since 1970 */
X    d = ctime(&clock);
X    strcpy(ptr, d);
X
X    d = ptr + 8;
X    if (*d == ' ') {
X        *d = *(d+1);
X        *++d = ' ';
X    }
X    d = ptr + 11;
X    if (*d == '0')
X        *d = ' ';
X    if ((hour = atoi(d)) > 11) {    /* PM */
X        if (hour > 12)
X            sprintf(d, "%2d", hour -12);
X        d+=2;
X        *d = ':';
X        d+=3;
X        *d++ = '.';
X    }
X    else {
X        d = ptr + 16;
X        *d++ = ' ';
X    }
X    *d = '\0';  /* delete :seconds, year, newline */
X
X#ifdef LOCALTEST
X    printf("    01234567890123456789012\n>>>>%s<<<<\n", ptr);
X    alarm(10);
X    if (signal(SIGALRM, cdate) == BADSIG)
X         exit(1);
X#else
X    getyx(stdscr, savy, savx);
X
X#ifdef sun
X    se = !((stdscr->_y[stdscr->_cury][stdscr->_curx] & 128));
X#else
X    se = (stdscr->_y[stdscr->_cury][stdscr->_curx] < 128);
X#endif
X    if (se)
X        standout();
X    mvaddstr(TOP,  CONVLEFT, ptr);
X    if (se)
X        standend();
X    move(savy, savx);
X    refresh();
X    alarm(10);
X    if (signal(SIGALRM, cdate) == BADSIG)
X         fatal("clock signal");
X    TR_
X}
X
Xclockoff()
X{
X    static char *fid = "clockoff";
X
X    _TR
X    alarm(0);
X    if (signal(SIGALRM, SIG_DFL) == BADSIG)
X         fatal("clock signal at off");
X    TR_
X}
X
Xpfresh()
X{
X    static char *fid = "pfresh";
X    _TR
X    if (Clockstat == DISA)
X        refresh();
X    else {
X        clockoff();
X        refresh();
X        cdate();
X    }
X#endif
X
X    TR_
X}
X
Xyear()
X{
X    long clock;
X    static char ptr[30];
X    static char *fid = "year";
X
X    _TR
X    clock = time((long *) 0);
X    strcpy(ptr, ctime(&clock));
X
X    Thisyear = ptr + 20;
X    *(ptr + 24) = '\0'; /* kill newline */
X    TR_
X}
X
Xwhichmonth(ptr)
Xchar *ptr;
X{
X    register int hv = 0;
X    register char *hp;
X
X    static char hashbuf[] = {
X      12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0,
X       3, 0, 0, 4, 0, 0,10, 5, 9, 0, 0, 7, 0, 6, 0, 0, 0, 0, 0,11, };
X    static char *fid = "whichmonth";
X
X    _TR
X    hp = ptr;
X    if (hp == ZERO) {
X        TR_
X        return(0);
X    }
X    if (isalpha(*hp)) {
X        hv += (*hp++ & 95);
X        if (*hp) {
X            hv += (*hp++ & 95);
X            if (*hp)
X                hv += (*hp & 95);
X        }
X        hv -= 204;
X        if (hv < 0 || hv > 39) {
X            TR_
X            return(0);
X    }
X        return(hashbuf[hv]);
X    }
X    if ((hv = atoi(hp)) > 12 || hv < 1) {
X        TR_
X        return(0);
X    }
X    TR_
X    return(hv);
X}
SHAR_EOF
$TOUCH -am 0221173890 time.c &&
chmod 0644 time.c ||
echo "restore of time.c failed"
set `wc -c time.c`;Wc_c=$1
if test "$Wc_c" != "3249"; then
	echo original size 3249, current size $Wc_c
fi
# ============= total.c ==============
echo "x - extracting total.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > total.c &&
X/* total.c */
X/**********************************************************************
X*    File Name     : total.c
X*    Function      : pac checkbook balancer (totalizer)
X*    Author        : Istvan Mohos, 1987
X***********************************************************************/
X
X#include "defs.h"
X#define TOTALMAP
X#include "maps.h"
X#undef TOTALMAP
X
Xstatic double Su[FITCONV - 2];
Xstatic double Total;
X
Xtotal()
X{
X    int pyp, pxp;
X    char curr_l[CONVMAX + 1];
X    register int ri, rj;
X    static int f_id = 0;
X    int where, ck, copy;
X    static char *fid = "total";
X    
X    _TR
X    CYX;
X    Tqlev = TALYREQ;
X    if (Clockstat == DISA)
X        Titlq[TALYREQ] = Sb[TALYREQ];
X    else
X        Titlq[TALYREQ] = Cb[TALYREQ];
X    Basq[TALYREQ] = Bb[TALYREQ];
X    standout();
X    for (ri = FITCONV - 2, rj = 115; --ri >= 0; rj--)
X        mvaddch(UTOP + ri, RBOUND, rj);
X    mvaddch(TOP + FITCONV, RBOUND, 't');
X    standend();
X    clear_wline(TOP+FITCONV-1, CONVLEFT, RBOUND-2, 0, 1);
X    show_items();
X    show_total(0);
X    update();
X 
X    while(1) {
X    
X        where = UTOP + f_id;
X        if (Su[f_id] == 0.)
X            clear_wline(where, CONVLEFT, RBOUND-2, 0, 1);
X    
X
X        ck = ledit(curr_l, tot_map, where, CONVLEFT, RBOUND-2, 0, 1, 1);
X    
X        if (!*curr_l)
X            strcpy(curr_l, "0.0");
X
X        switch(ck) {
X            case 6:  /* wants to write file */
X            case 16:
X                if (Totcopy == ENA || Totcopy == AP) {
X                    show_total(1);
X                    Totcopy = DISA;
X                    close(Tc);
X                    Tc = -1;
X                }
X                else {
X                    show_total(0);
X                    (ck == 6) ? (Totcopy = ENA) : (Totcopy = AP);
X                }
X                hard(1);
X                break;
X
X            case 0:  /* normal return, did read line */
X                show_line(f_id, curr_l);
X                if (++f_id > FITCONV -3) {
X                    show_total(1);
X                    f_id = 1;
X                    for (ri = FITCONV - 2; --ri > 0; Su[ri] = 0.);
X                    Su[0] = Total;
X                    show_items();
X                }
X                show_total(0);
X                break;
X
X            case 'T':
X                show_line(f_id, curr_l);
X                show_total(1);
X                break;
X
X            case 1:
X                show_line(f_id, curr_l);
X                show_total(ck);
X                PYX;
X                Basq[TALYREQ] = ZERO;
X                update();
X                pfresh();
X                TR_
X                return;
X
X            case 3:   /* control-c, clear entire window */
X                f_id = 0;
X                for (ri = FITCONV - 2; --ri >= 0; Su[ri] = 0.);
X                show_items();
X                show_total(0);
X                break;
X
X            default:
X                if (ck > 64 && ck < 84) {   /* A through S */
X                    show_line(f_id, curr_l);
X                    show_total(0);
X                    f_id = ck - 'A';
X                }
X                else {
X                    if ((copy = ck - 97) < FITCONV - 2) /* a to s */
X                        sprintf(curr_l, "%*.*f", CONVMAX, Precision,
X                            Su[copy]);
X                    else /* t */
X                        sprintf(curr_l, "%*.*f", CONVMAX, Precision,
X                            Total);
X                    show_line(f_id, curr_l);
X                    if (++f_id > FITCONV -3) {
X                        show_total(1);
X                        f_id = 1;
X                        for (ri = FITCONV - 2; --ri > 0; Su[ri] = 0.);
X                        Su[0] = Total;
X                        show_items();
X                    }
X                    show_total(0);
X                }
X                break;
X        }
X    }
X}
X
Xshow_total(transfer)
Xint transfer;
X{
X    char floatbuf[WINLINE];
X    char hardbuf[WINLINE];
X    register char *fb = floatbuf;
X    register int rx;
X    register int ri;
X    struct  stk_cell *sr;
X    static char *fid = "show_total";
X    
X    _TR
X    Total = 0.;
X    for (ri = FITCONV - 2; --ri >= 0; Total += Su[ri]);
X    sprintf(fb, "%*.*f", CONVMAX, Precision, Total);
X    if ((ri = strlen(floatbuf)) <= CONVMAX) {
X        *(fb = floatbuf + ri++) = '.';
X        *++fb = 0;
X    }
X    for (fb = floatbuf + ri; --fb >= floatbuf;)
X        if (*fb == '.')
X            break;
X    if (fb < floatbuf)  {
X        Total = 0.;
X        sprintf(floatbuf, "%*.*f", CONVMAX, Precision, Total);
X    }
X    *((fb = floatbuf) + CONVMAX) = 0;
X    mvaddstr(TOP + FITCONV, CONVLEFT, fb);
X    if (transfer) {
X        if (Tc != -1) {
X            if (Hf != FXTER) {
X                if ((write(Tc, "\n", 1)) != 1)
X                    fatal("total write");
X                for (ri = UTOP; ri < UTOP + FITCONV - 2; ri++) {
X                    fb = hardbuf;
X                    *fb++ = ri + 'a' - UTOP;
X                    *fb++ = ' ';
X                    *fb++ = ' ';
X                    *fb++ = ' ';
X                    for (rx = CONVLEFT; rx < RBOUND -1; rx++)
X                        *fb++ = stdscr->_y[ri][rx] & 127;
X                    *fb = '\n';
X                    if ((write(Tc, hardbuf, 4+CONVMAX+1))
X                        != 4+CONVMAX+1)
X                        fatal("total 2 write");
X                }
X                if ((write(Tc,"    -----------------\nt   ", 26)) != 26)
X                    fatal("total 3 write");
X                if ((write(Tc, floatbuf, CONVMAX)) != CONVMAX)
X                    fatal("total 4 write");
X                if ((write(Tc, "\n\n", 2)) != 2)
X                    fatal("total 5 write");
X            }
X            else {
X                if ((write(Tc, floatbuf, CONVMAX)) != CONVMAX)
X                    fatal("total 6 write");
X                if ((write(Tc, "\n", 1)) != 1)
X                    fatal("total 7 write");
X            }
X        }
X        if (Stack == ENA)
X            pushstack(1);
X        /* strip trailing zeros */
X        for (fb = floatbuf + strlen(floatbuf); --fb >= floatbuf;)
X            if (*fb == '.')
X                break;
X        if (fb >= floatbuf) {
X            for (fb += strlen(fb); *--fb == '0'; *fb = 0);
X            if (*fb == '.')
X                *fb = 0;
X        }
X        /* strip preceding spaces */
X        for (fb = floatbuf; *fb == ' '; fb++);
X
X        sr = find(1);
X        sprintf(sr->cell, "%c %-*.*s", *(Base_str + 10),
X            STACKMAX-2, STACKMAX-2, fb);
X        show_stack();
X    }
X    TR_
X}
X
Xshow_line(f_id, buf)
Xint f_id;
Xchar *buf;
X{
X    char floatbuf[WINLINE];
X    char transbuf[WINLINE];
X    register char *fb;
X    register char *T = transbuf;
X    char *secp;
X    double thisval;
X    double first = 0., second;
X    int where, ri, oper = 0;
X    static char *fid = "show_line";
X    
X    _TR
X    where = UTOP + f_id;
X
X    /* strip embedded spaces */
X    fb = buf;
X    while (*fb) {
X        switch(*fb) {
X            case ' ':
X                break;
X            case '*':
X            case '@':
X                *T++ = 0;
X                secp = T;
X                oper = 1;
X                break;
X            case '+':
X                *T++ = 0;
X                secp = T;
X                oper = 2;
X                break;
X            default:
X                *T++ = *fb;
X                break;
X        }
X        fb++;
X    }
X    *T = 0;
X    switch(oper) {
X        case 0:
X        default:
X            thisval = atof(transbuf);
X            break;
X        case 1:
X            if (*transbuf) 
X                thisval = first = atof(transbuf);
X            if (*secp) {
X                second = atof(secp);
X                thisval = first * second;
X            }
X            break;
X        case 2:
X            if (*transbuf) 
X                thisval = first = atof(transbuf);
X            if (*secp) {
X                second = atof(secp);
X                if (second != 0.)
X                    thisval = first + second;
X            }
X            break;
X    }
X    Su[f_id] = thisval;
X    sprintf(floatbuf, "%*.*f", CONVMAX, Precision, thisval);
X    if ((ri = strlen(floatbuf)) <= CONVMAX) {
X        *(fb = floatbuf + ri++) = '.';
X        *++fb = 0;
X    }
X    for (fb = floatbuf + ri; --fb >= floatbuf;)
X        if (*fb == '.')
X            break;
X    if (fb < floatbuf)  {
X        Su[f_id] = 0.;
X        sprintf(floatbuf, "%*.*f", CONVMAX, Precision, Su[f_id]);
X    }
X    *((fb = floatbuf) + CONVMAX) = 0;
X    mvaddstr(where, CONVLEFT, floatbuf);
X    TR_
X}
X
Xshow_items()
X{
X    char floatbuf[WINLINE];
X    char *fb = floatbuf;
X    register int ri;
X    static char *fid = "show_items";
X
X    _TR
X    for (ri = FITCONV - 2; --ri >= 0;) {
X        sprintf(fb, "%*.*f", CONVMAX, Precision, Su[ri]);
X        *(fb + CONVMAX) = 0;
X        mvaddstr(UTOP + ri, CONVLEFT, fb);
X    }
X    TR_
X}
SHAR_EOF
$TOUCH -am 0221163890 total.c &&
chmod 0644 total.c ||
echo "restore of total.c failed"
set `wc -c total.c`;Wc_c=$1
if test "$Wc_c" != "8736"; then
	echo original size 8736, current size $Wc_c
fi
# ============= version.c ==============
echo "x - extracting version.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > version.c &&
Xchar *version = "Wed Feb 21 16:39:20 EST 1990";
SHAR_EOF
$TOUCH -am 0221163990 version.c &&
chmod 0644 version.c ||
echo "restore of version.c failed"
set `wc -c version.c`;Wc_c=$1
if test "$Wc_c" != "48"; then
	echo original size 48, current size $Wc_c
fi
# ============= work.c ==============
echo "x - extracting work.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > work.c &&
X/* work.c */
X/**********************************************************************
X*    File Name     : work.c
X*    Function      : general pac subroutines
X*    Author        : Istvan Mohos, 1987
X***********************************************************************/
X
X#include "defs.h"
X
Xclear_accwin()
X{
X    static char *fid = "clear_accwin";
X
X    _TR
X    mvaddstr(ACCUM,ULEFT,Sp44);
X    TR_
X}
X
X/* pointer should sit on a null byte, as given by things like
X   "buf + sizeof(buf)", fill backwards with spaces
X   including the next null byte found. */
Xrev_clear(ptr)
Xchar *ptr;
X{
X    register char *rp;
X    static char *fid = "rev_clear";
X
X    _TR
X    for (rp = ptr;;)
X        if (*--rp == '\0') {
X            *rp = ' ';
X             break;
X        }
X        else
X             *rp = ' ';
X    TR_
X}
X
Xclear_wline(ver, lbound, rbound, video, lines)
Xint ver, lbound, rbound, video, lines;
X{
X    register ri, rj;
X    static char *fid = "clear_wline";
X
X    _TR
X    if (!lines)
X        lines = 1;
X    if (video)
X        standout();
X    for (rj = ver+lines; --rj >= ver;) {
X        move(rj, lbound);
X        for (ri = rbound - lbound + 1; --ri >= 0; addch(' '));
X    }
X    if (video)
X        standend();
X    move(CY,CX);
X    TR_
X}
X
X/* spacefills string to max: digit characters, appends '\0'; in Tokbuf.
X   returns -1 if string is longer than digit */
X
Xspacefill(string, digits)
Xchar *string;
Xint digits;
X{
X    register char *reg_c;
X    register char r_count;
X    static char *fid = "spacefill";
X
X    _TR
X    if ((r_count = strlen(string)) > digits) {
X        TR_
X        return(-1);
X    }
X    strcpy(Tokbuf, string);
X    reg_c = &Tokbuf[r_count];
X    while(r_count < digits ) {
X        *reg_c++ = ' ';
X        ++r_count;
X    }
X    Tokbuf[digits] = '\0';
X    TR_
X    return(0);
X}
X
Xaddto_controlbuf(c_ptr)
Xchar *c_ptr;
X{
X    static char *fid = "addto_controlbuf";
X
X    _TR
X    strcat(Controlbuf, "\\\n"); /* prevent oversize input string */
X    strcat(Controlbuf, c_ptr);
X    TR_
X}
X
Xaddto_ubuf(c_ptr)
Xchar *c_ptr;
X{
X    static char *fid = "addto_ubuf";
X
X    _TR
X    strcat(Ubuf, "\\\n"); /* prevent oversize input string */
X    strcat(Ubuf, c_ptr);
X    TR_
X}
X
Xupcase(char_p)
Xchar *char_p;
X{
X    register char *rcp = char_p;
X    static char *fid = "upcase";
X
X    _TR
X    do
X        if (isalpha(*rcp))
X            *rcp &= 95;
X    while (*rcp++ != '\0');
X    TR_
X}
X
Xpacinit()
X{
X    Format    = FORM_DFLT;
X    (Format == COMMA_) ? (Separator = ',') : (Separator = ' ');
X    Hf        = HF_DFLT;
X    Ibase     = IB_DFLT;
X    Oldib     = IB_DFLT;
X    Obase     = OB_DFLT;
X    Oldob     = OB_DFLT;
X    Lastob    = OB_DFLT;
X    Show      = SHOW_DFLT;
X    Justify   = JUS_DFLT;
X    Precision = PREC_DFLT;
X    Stack     = STACK_DFLT;
X    Staybase  = DISA;
X    Autoconv  = DISA;
X}
X
Xint
Xround(nump, endp)
Xchar *nump, *endp;
X{
X    register char *fr, *to, *dp;
X    int done = 0;
X    int dpfound = 0;
X
X    for (fr = nump, dp = endp; --dp >= fr;)
X        if (*dp == '.') {
X            dpfound = 1;
X            break;
X        }
X
X    if (!dpfound)
X        return(-1);
X
X    fr = endp - 1;
X    if (*fr < 53) { /* last digit less than 5 */
X        *fr = '\0';
X        return(0);
X    }
X
X    /* write new values in freed-up byte at right */
X    for (to = endp - 1, done = 0; --fr > dp;) {
X        if (*fr == '9')
X            *to-- = '0';
X        else {
X            *to-- = *fr + 1;
X            done = 1;
X            break;
X        }
X    }
X
X    if (done) { /* left-shift new values back 1 byte */
X        for (dp = endp -1; to <= dp;)
X            *fr++  = *++to;
X        *dp = '\0';
X        return(0);
X    }
X
X    *to-- = *fr; /* new decimal point */
X
X    for (dp = nump, done = 0; --fr >= dp;) {
X        if (*fr == '9')
X            *to-- = '0';
X        else {
X            if (*fr > 47 && *fr < 57) {
X                *to-- = *fr + 1;
X                done = 1;
X                break;
X            }
X            else {        /* fr got to the left of the first digit */
X                *to = '1';
X                return(1);
X            }
X        }
X    }
X
X    if (done) { /* left-shift new values back 1 byte */
X        for (++to, dp = endp -1; to <= dp;)
X            *fr++  = *to++;
X        *dp = '\0';
X        return(0);
X    }
X
X    *dp = '1';
X    return(1);
X
X}
X
SHAR_EOF
$TOUCH -am 0221163890 work.c &&
chmod 0644 work.c ||
echo "restore of work.c failed"
set `wc -c work.c`;Wc_c=$1
if test "$Wc_c" != "4228"; then
	echo original size 4228, current size $Wc_c
fi
exit 0