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

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

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

==============================CUT HERE==============================
#!/bin/sh
# This is part 03 of a multipart archive
if touch 2>&1 | fgrep '[-amc]' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= conv.c ==============
echo "x - extracting conv.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > conv.c &&
X/* conv.c */
X/**********************************************************************
X*    File Name     : conv.c
X*    Function      : user conversion routines of pac
X*                  : Recursion is too big a task to fit the framework
X*                  :  (i.e. defining 'to foo' as 'to {to foo}' brings
X*                  :  up all sorts of control problems).  To simplify,
X*                  :  only numerical expressions and binary operands
X*                  :  are permitted, in a single statement (no ';').
X*                  : 
X*    Author        : Istvan Mohos, 1987
X***********************************************************************/
X
X
X#include "defs.h"
X#define CONVMAP
X#include "maps.h"
X#undef CONVMAP
X
Xshow_uconv()
X{
X    register ri;
X    static char *fid = "show_uconv";
X
X    _TR
X    if (Convsel < CENTER)
X        Topconv = 0;
X    else if (Convsel >= Convcount - CENTER)
X        Topconv = Convcount - (2 * CENTER);
X    else
X        Topconv = Convsel - CENTER + 1;
X
X    for (ri = 0; ri < FITCONV; ri++) {
X        mvaddstr(ri + TOP+1, CONVLEFT, Convlist[ri + Topconv][0]);
X        addch(' ');
X        mvaddstr(ri + TOP+1, KEYLEFT, Convlist[ri + Topconv][1]);
X    }
X
X    standout();
X    for (ri = 0; ri < FITCONV; ri++)
X        mvaddch(UTOP + ri, RBOUND, ' ');
X
X    mvaddstr(TOP+1 + Convsel - Topconv, CONVLEFT, Convlist[Convsel][0]);
X    standend();
X    TR_
X}
X
Xsetup_uconv()
X{
X    register char *rc;
X    register int ri;
X    static char *fid = "setup_uconv";
X
X    _TR
X    Convhsiz = Convcount * (FROMTOSIZ + KEYSIZ);
X    for (ri = 0; ri < Convcount; ri++)
X        Convhsiz += strlen(Convlist[ri][2]) + 1; /* conv string + \n */
X    if ((Convhom = calloc(Convhsiz, 1)) == ZERO)
X        fatal("calloc error in setup_uconv");
X
X    /* move static defs to dynamically alterable Convhom buffer */
X    for (rc = Convhom, ri = 0; ri < Convcount; ri++) {
X        strcpy(rc, Convlist[ri][0]);
X        rc += FROMTOSIZ;
X        strcpy(rc, Convlist[ri][1]);
X        rc += KEYSIZ;
X        strcpy(rc, Convlist[ri][2]);
X        while (*rc++ != '\0');
X    }
X    realign_conv();
X    TR_
X}
X
Xconv_id(c_ptr)
Xchar *c_ptr;
X{
X    int inlist_val, under;
X    static char *fid = "conv_id";
X
X    _TR
X    if ((inlist_val = spacefill(c_ptr, 3)) != -1)
X        inlist_val = keysearch(Tokbuf, Convcount, &under);
X    TR_
X    return(inlist_val);
X}
X
Xkeysearch (key, max, under)
Xregister char *key;
Xint max, *under;
X{
X    register int guess, mid, lo = 0, hi;
X    static char *fid = "keysearch";
X
X    _TR
X    hi = max - 1;
X    while (lo <= hi) {
X        mid = (lo + hi) >> 1;
X        if ((guess = strcmp(key, Convlist[mid][1])) < 0)
X            hi = mid - 1;
X        else if (guess > 0)
X            lo = mid + 1;
X        else {
X            TR_
X            return(mid);
X        }
X    }
X    *under = lo;
X    TR_
X    return (-1);
X}
X
Xnewconv()
X{
X    int c;
X    int lbound;
X    char calbuf[LINEMAX];
X    int pyp, pxp;
X    int ri;
X    register int rj;
X    register char *rc;
X    static char *fid = "newconv";
X
X    _TR
X    CYX;
X    rc = calbuf;
X    for (ri = UTOP; ri <= UBOT; ri++)
X        for (rj = ULEFT; rj <= URIGHT; rj++)
X            *rc++ = stdscr->_y[ri][rj];
X
X    mvaddstr(UTOP, ULEFT, Sp44);
X    mvaddstr(UTOP + 1, ULEFT, Sp44);
X    mvaddstr(UTOP + 2, ULEFT, Sp44);
X
X    if (Convcount == 255) {
X        mvaddstr(UTOP, ULEFT,
X            "SELECT:   ...full...    Remove     Change  _");
X        lbound = ULEFT + strlen(
X            "SELECT:   ...full...    Remove     Change  ");
X
X        while((c = ledit(ZERO,c_sel_map,UTOP,lbound,lbound,0,0,0)
X            | 32) != 'r' && c != 'c');
X    }
X    else if (Convcount == 22) {
X        mvaddstr(UTOP, ULEFT,
X            "SELECT:     Install   ...low...    Change  _");
X        lbound = ULEFT + strlen(
X            "SELECT:     Install   ...low...    Change  ");
X
X        while((c = ledit(ZERO,c_sel_map,UTOP,lbound,lbound,0,0,0)
X            | 32) != 'i' && c != 'c');
X    }
X    else {
X        mvaddstr(UTOP, ULEFT,
X            "SELECT:     Install     Remove     Change  _");
X        lbound = ULEFT + strlen(
X            "SELECT:     Install     Remove     Change  ");
X
X        while((c = ledit(ZERO,c_sel_map,UTOP,lbound,lbound,0,0,0)
X            | 32) != 'i' && c != 'r' && c != 'c');
X    }
X
X    mvaddstr(UTOP, ULEFT, Sp44);
X    mvaddstr(UTOP + 1, ULEFT, Sp44);
X    mvaddstr(UTOP + 2, ULEFT, Sp44);
X
X    switch(c) {
X        case 'i':
X            addnew(specify(pyp, pxp));
X            break;
X
X        case 'r':
X            remove(celect());
X            break;
X
X        case 'c':
X            remove(celect());
X            addnew(specify(pyp, pxp));
X            break;
X    }
X
X    rc = calbuf;
X    for (ri = UTOP; ri <= UBOT; ri++)
X        for (rj = ULEFT; rj <= URIGHT; rj++)
X            mvaddch(ri, rj, *rc++);
X
X    PYX;
X    pfresh();
X    TR_
X}
X
Xcelect()
X{
X    int lbound, rbound;
X    char *c_key;
X    int keylen, old_id, dummy;
X    static char *fid = "celect";
X
X    _TR
X    clear_wline(UTOP, ULEFT, URIGHT, 0, 3);
X    c_key = "   ";
X    mvaddstr(UTOP, ULEFT,
X        "ENTER OLD 'TO' SEARCH KEY:   [");
X    lbound = ULEFT + strlen(
X        "ENTER OLD 'TO' SEARCH KEY:   [");
X    rbound = lbound + 2;
X    mvaddstr(UTOP, rbound + 1, "]");
X
X    old_id = -1;
X    while (old_id == -1) {
X        mvaddstr(UTOP, lbound, c_key);
X    
X
X        ledit(&K_buf[0], c_ed_map, UTOP, lbound, rbound, 0, 1, 1);
X        /* stripping surrounding spaces */
X
X        if(!*K_buf)
X            continue;
X        keylen = strlen(K_buf);
X        if (keylen < 3)
X            K_buf[2] = ' ';
X        else if (*(K_buf+1) == ' ')
X            *(K_buf+1) = '_'; /* turn embedded space into _ */
X        if (keylen < 2)
X            K_buf[1] = ' ';
X        old_id = keysearch(K_buf, Convcount, &dummy);
X    }
X    TR_
X    return(old_id);
X}
X
Xspecify(pyp, pxp)
Xint pyp, pxp;
X{
X    int lbound, rbound;
X    char *c_label, *c_key;
X    int neednewkey = 1, keylen, insert;
X    static char *fid = "specify";
X
X    _TR
X    clear_wline(UTOP, ULEFT, URIGHT, 0, 3);
X    while (neednewkey) {
X        c_key = "   ";
X        mvaddstr(UTOP + 1, ULEFT,
X            "ENTER NEW 'TO' SEARCH KEY:   [");
X        lbound = ULEFT + strlen(
X            "ENTER NEW 'TO' SEARCH KEY:   [");
X        mvaddstr(UTOP + 1, lbound, c_key);
X        rbound = lbound + 2;
X        mvaddstr(UTOP + 1, rbound + 1, "]");
X    
X
X        ledit(&K_buf[0], c_ed_map, UTOP+1, lbound, rbound, 0, 1, 1);
X        /* stripping surrounding spaces */
X
X        if (keylen = strlen(K_buf)) {
X            if (keylen < 3)
X                K_buf[2] = ' ';
X            else if (*(K_buf+1) == ' ')
X                *(K_buf+1) = '_'; /* turn emmbedded space into _ */
X            if (keylen < 2)
X                K_buf[1] = ' ';
X        }
X        else
X            continue;
X        if (keysearch(K_buf, Convcount, &insert) == -1)
X            neednewkey = FALSE;
X        /* if it did find it, the proposed new key is a duplicate,
X           and is disallowed */
X    }
X
X    c_label = "             ";
X    mvaddstr(UTOP + 2, ULEFT, "ENTER 'CONVERSIONS' LABEL:   [");
X    lbound = ULEFT + strlen( "ENTER 'CONVERSIONS' LABEL:   [");
X    mvaddstr(UTOP + 2, lbound, c_label);
X    rbound = lbound + 12;
X    mvaddstr(UTOP + 2, rbound + 1, "]");
X
X
X    ledit(&L_buf[0], c_ed_map, UTOP+2, lbound, rbound, 0, 0, 1);
X
X    mvaddstr(UTOP, ULEFT, Sp44);
X    mvaddstr(UTOP + 1, ULEFT, Sp44);
X    mvaddstr(UTOP + 2, ULEFT, Sp44);
X
X    mvaddstr(UTOP, ULEFT,
X        "COMPLETE THE EQUATION USING THE BACKSLASH \\");
X    mvaddstr(UTOP + 1, ULEFT,
X        "CHARACTER TO REPRESENT THE 'FROM' QUANTITY.");
X    mvaddstr(UTOP + 2, ULEFT,
X        "CONSTANTS ARE INTERPRETED IN DECIMAL RADIX.");
X
X    Basq[EDITREQ] = Bb[EDITREQ];
X    update();  /* this returns to the original coordinates,
X                  but does'nt pfresh */
X
Xenter_conv:
X
X    ledit(&Eq_buf[0], eq_ed_map, BOT, FBOUND, RBOUND, 1, 1, 1);
X
X    if (verify_uconv())
X        goto enter_conv;
X
X    Basq[EDITREQ] = ZERO;
X    PYX;
X    update();
X    pfresh();
X    TR_
X    return(insert);
X}
X
Xrealign_conv()
X{
X    register int ri;
X    register char *rc;
X    static char *fid = "realign_conv";
X
X    _TR
X    for (rc = Convhom, ri = 0; ri < Convcount; ri++) {
X        Convlist[ri][0] = rc; /* ptr to first word of conversion */
X        rc += FROMTOSIZ;         /* buffer pointer to second word */
X        Convlist[ri][1] = rc; /* ptr to 2nd word of conversion */
X        rc += KEYSIZ;            /* buffer pointer to conv string */
X        Convlist[ri][2] = rc; /* ptr to conversion string */
X        while (*rc++ != '\0');   /* find next conversion in buffer */
X    }
X    TR_
X}
X
Xremove(old_id)
Xint old_id;
X{
X/*
X   malloc Convhsiz size temp buffer;
X   copy Convhom into temp until old_id conversion;
X   skip (do not copy) old_id conversion;
X   copy rest of Convhom into temp;
X   free Convhom;
X   assign Convhom pointer to temp;
X   decrement Convcount;
X   adjust Convhsiz;
X   realign Convlist pointers along new buffer;
X*/
X
X    char *Tmp;
X    register char *tp;
X    unsigned rmsiz;
X    register int ri;
X    static char *fid = "remove";
X
X    _TR
X    if ((Tmp = malloc(Convhsiz)) == ZERO)
X        fatal("malloc error in remove");
X    tp = Tmp;
X
X    for (ri = 0; ri < old_id; ri++) {
X        strcpy(tp, Convlist[ri][0]);
X        tp += FROMTOSIZ;
X        strcpy(tp, Convlist[ri][1]);
X        tp += KEYSIZ;
X        strcpy(tp, Convlist[ri][2]);
X        while (*tp++ != '\0');
X    }
X    rmsiz = FROMTOSIZ + KEYSIZ + strlen(Convlist[ri][2]) + 1; 
X    for (ri = old_id + 1; ri < Convcount; ri++) {
X        strcpy(tp, Convlist[ri][0]);
X        tp += FROMTOSIZ;
X        strcpy(tp, Convlist[ri][1]);
X        tp += KEYSIZ;
X        strcpy(tp, Convlist[ri][2]);
X        while (*tp++ != '\0');
X    }
X    free(Convhom);
X    Convhom = Tmp;
X    --Convcount;
X    Convhsiz -= rmsiz;
X    realign_conv();
X    if (Convsel > old_id)
X        --Convsel;
X    else if (Convsel == old_id)
X        Convsel = CONVSEL;
X    show_uconv();
X    TR_
X}
X
Xaddnew(insert)
Xint insert;
X{
X/*
X   Malloc new buffer, to hold Convhom + size of new conversion.
X   Copy Convhom into new buffer, until the alphabetic ordering
X       of KEYs reaches the new KEY.
X   Insert new conversion in new buffer.
X   Finish copying old conversions from Convhom to new buffer.
X   Free Convhom.
X   Assign Convhom (pointer) to new buffer.
X   Increment Convcount.
X   adjust Convhsiz;
X   Realign Convlist pointers along new buffer.
X*/
X
X    char *Tmp;
X    register char *tp;
X    unsigned addsiz;
X    register int ri;
X    static char *fid = "addnew";
X
X    _TR
X    addsiz = FROMTOSIZ + KEYSIZ + strlen(Eq_buf) + 1; 
X    if ((Tmp = malloc(Convhsiz + addsiz)) == ZERO)
X        fatal("malloc error in addnew");
X    tp = Tmp;
X
X    for (ri = 0; ri < insert; ri++) {
X        strcpy(tp, Convlist[ri][0]);
X        tp += FROMTOSIZ;
X        strcpy(tp, Convlist[ri][1]);
X        tp += KEYSIZ;
X        strcpy(tp, Convlist[ri][2]);
X        while (*tp++ != '\0');
X    }
X    strcpy(tp, L_buf);
X    tp += FROMTOSIZ;
X    strcpy(tp, K_buf);
X    tp += KEYSIZ;
X    strcpy(tp, Eq_buf);
X    while (*tp++ != '\0');
X    for (ri = insert; ri < Convcount; ri++) {
X        strcpy(tp, Convlist[ri][0]);
X        tp += FROMTOSIZ;
X        strcpy(tp, Convlist[ri][1]);
X        tp += KEYSIZ;
X        strcpy(tp, Convlist[ri][2]);
X        while (*tp++ != '\0');
X    }
X    free(Convhom);
X    Convhom = Tmp;
X    ++Convcount;
X    Convhsiz += addsiz;
X    realign_conv();
X    Convsel = insert;
X    show_uconv();
X    TR_
X}
X
Xverify_uconv()
X{
X    static char *fid = "verify_uconv";
X
X    _TR
X    if (strlen(Eq_buf) == 0) {
X        strcpy(Eq_buf, "\\");
X        TR_
X        return(0);
X    }
X
X    TR_
X    return(0);
X}
X
X/* the routine that interprets the user keyword TO */
Xconv_usr()
X{
X    char *ctab, *cb, cbuf[LINEMAX];
X    char hardbuf[LINEMAX];
X    int ri;
X    int sav_ibase;
X    static char *fid = "conv_usr";
X
X    _TR
X    e_syntax();
X    e_divby0();
X    e_exponent();
X    e_bcexec();
X
X    if (!Bc_error) {
X        sav_ibase = Ibase;
X        Ibase = 10;
X        conv_bc(Mainbuf, ZERO, 0, 0);
X        *(Convbuf + DIGMAX + 2) = '\0';
X        ri = strlen(Convbuf);
X        Ibase = sav_ibase;
X    
X        cb = cbuf;
X        strcpy(cb, "ibase=A;");
X        cb += strlen(cb);
X    
X        ctab = Convlist[Convsel][2];
X        sprintf(Bb[CONVREQ] + BUFSTOP, ctab);
X        rev_clear(Bb[CONVREQ] + TITSIZ);
X        Basq[CONVREQ] = Bb[CONVREQ];
X        update();
X    
X        if ( Hc != -1 && Hf != FXTER) {
X            if (Hf == FVER)
X                sprintf(hardbuf, "TO %s: %s\n", Convlist[Convsel][1], ctab);
X            else
X                sprintf(hardbuf, "TO %s\n", Convlist[Convsel][1]);
X            if ((write(Hc, hardbuf, strlen(hardbuf))) !=
X                strlen(hardbuf))
X                fatal("hardcopy write");
X        }
X    
X        while (*ctab != '\0') {
X            if (*ctab == '\\') {
X                strcpy(cb, Convbuf);
X                cb += ri;
X                ctab++;
X            }
X            else
X                *cb++ = *ctab++;
X        }
X        sprintf(cb, ";ibase=%d\n", Ibase);
X        if (write(A_write[1], cbuf, strlen(cbuf)) == -1)
X            fatal("main pipe write");
X        clear_accwin();
X        wait_main_pipe();
X    }
X    if (Autoconv == DISA)
X        Do_conv = FALSE;
X    TR_
X}
X
SHAR_EOF
$TOUCH -am 0221163890 conv.c &&
chmod 0644 conv.c ||
echo "restore of conv.c failed"
set `wc -c conv.c`;Wc_c=$1
if test "$Wc_c" != "13160"; then
	echo original size 13160, current size $Wc_c
fi
# ============= convbase.c ==============
echo "x - extracting convbase.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > convbase.c &&
X/* convbase.c */
X/**********************************************************************
X*    File Name     : convbase.c
X*    Function      : use second bc pipe for conversion between radices
X*    Author        : Istvan Mohos, 1987
X***********************************************************************/
X
X#include "defs.h"
X#include "toktab.h"
X#define INTERMAP
X#include "maps.h"
X#undef INTERMAP
X
Xchar *
Xsubstivar(found, token, ib)
Xchar *token;
Xint found, ib;
X{ 
X    static char res[PIPEMAX];
X    static struct stk_cell *sr = &Stk[0];
X    static char *fid = "substivar";
X    char *ret = res;
X    int tokval;
X
X    _TR
X    if (found == -1) {
X        if (token == ZERO) {
X            TR_
X            return(ZERO);
X        }
X        tokval = lookup(token);
X    }
X    else
X        tokval = found;
X
X    switch(tokval) {
X        case H_:
X        case I_:
X        case J_:
X        case K_:
X        case L_:
X        case M_:
X        case N_:
X        case O_:
X        case P_:
X        case Q_:
X        case R_:
X        case S_:
X        case T_:
X        case U_:
X        case V_:
X        case W_:
X            onereg(*token - 'g');
X            conv_bc(Onebuf, res, 1, ib);
X            break;
X
Xcase PI: conv_bc("3.1415926535897932384626433832795028841971693993751",
X                    res, 10, ib); break;
Xcase ASTRO:     conv_bc("149504200", res, 10, ib); break;
X                    /* km */
Xcase AMASS:     conv_bc(".00000000000000000000000165975",
X                    res, 10, ib); break; /* grams */
Xcase AVOGADRO:  conv_bc("602502000000000000000000",
X                    res, 10, ib); break; /* per g mole */
Xcase BOLTZMANN: conv_bc(".000000000000000138040", res, 10, ib); break;
X                    /* erg/Kelvin */
Xcase ECHARGE:   conv_bc(".000000000160202", res, 10, ib); break;
X                    /* esu */
Xcase CHROMA:    conv_bc("1.0594631", res, 10, ib); break;
Xcase EMASS:     conv_bc(".000000000000000000000000000910820",
X                    res, 10, ib); break; /* grams */
Xcase EULER:     conv_bc(".577216", res, 10, ib); break;
Xcase FARADAY:   conv_bc("96521900", res, 10, ib); break;
X                    /* C/kmole */
Xcase G_:        conv_bc("9.80665", res, 10, ib); break;
X                    /* m/s2 */
Xcase GAS:       conv_bc("83169600", res, 10, ib); break;
X                    /* erg/g mole Kelvin */
Xcase GRAVITY:   conv_bc(".00000000006673", res, 10, ib); break;
X                    /* N m2/kg2 */
Xcase HEAT:      conv_bc("4.1855", res, 10, ib); break;
X                    /* J/cal */
Xcase LIGHT:     conv_bc("299792.50", res, 10, ib); break;
X                    /* km/sec */
Xcase LIGHTYEAR: conv_bc("9460530000000", res, 10, ib); break;
X                    /* km */
Xcase MOONMASS:  conv_bc("73430000000000000000000", res, 10, ib); break;
X                    /* kg */
Xcase SUNMASS:   conv_bc("1987000000000000000000000000000",
X                    res, 10, ib); break; /* kg */
Xcase EARTHMASS: conv_bc("5976500000000000000000000",
X                    res, 10, ib); break; /* kg */
Xcase NATURAL:   conv_bc("2.7182818284590452353602874713526",
X                    res, 10, ib); break;
Xcase NMASS:     conv_bc(".00000000000000000000000167465",
X                    res, 10, ib); break; /* grams */
Xcase PARSEC:    conv_bc("30837450000000", res, 10, ib); break;
X                    /* km */
Xcase PARALLAX:  conv_bc("8.794", res, 10, ib); break;
X                    /* " */
Xcase PLANCK:    conv_bc(".00000000000000000000000000662491",
X                    res, 10, ib); break; /* erg sec */
Xcase PMASS:     conv_bc(".00000000000000000000000167235",
X                    res, 10, ib); break; /* grams */
Xcase MOONRAD:   conv_bc("1738000", res, 10, ib); break;
X                    /* meters */
Xcase SUNRAD:    conv_bc("696500000", res, 10, ib); break;
X                    /* meters */
Xcase EARTHRAD:  conv_bc("6378388", res, 10, ib); break;
X                    /* meters */
Xcase RYDBERG:   conv_bc("10973732.8", res, 10, ib); break;
X                    /* per meter */
Xcase SOUND:     conv_bc("340.505", res, 10, ib); break;
X                    /* meters/sec: 331.4 + (.607 * Celsius) */
Xcase STEFAN:    conv_bc(".000000056693", res, 10, ib); break;
X                    /* J/m2 Kelvin4 sec */
Xcase TOMOON:    conv_bc("384400", res, 10, ib); break;
X                    /* km */
Xcase TOSUN:     conv_bc("149500000", res, 10, ib); break;
X                    /* km */
Xcase WIEN:      conv_bc(".289778", res, 10, ib); break;
X                    /* cm Kelvin */
X
Xcase MILLI:     conv_bc(".001", res, 10, ib); break;
Xcase MICRO:     conv_bc(".000001", res, 10, ib); break;
Xcase NANO:      conv_bc(".000000001", res, 10, ib); break;
Xcase PICO:      conv_bc(".000000000001", res, 10, ib); break;
Xcase FEMTO:     conv_bc(".000000000000001", res, 10, ib); break;
Xcase ATTO:      conv_bc(".000000000000000001", res, 10, ib); break;
Xcase KILO:      conv_bc("1000", res, 10, ib); break;
Xcase MEGA:      conv_bc("1000000", res, 10, ib); break;
Xcase GIGA:      conv_bc("1000000000", res, 10, ib); break;
Xcase TERA:      conv_bc("1000000000000", res, 10, ib); break;
Xcase PETA:      conv_bc("1000000000000000", res, 10, ib); break;
Xcase EXA:       conv_bc("1000000000000000000", res, 10, ib); break;
X
X        case X_LOWER:
X        case X_UPPER:
X            sprintf(res, "%s", sixteen[Ibase]);
X            break;
X
X        case BACKSLASH:
X            conv_bc(sr->cell, res, 1, ib);
X            break;
X
X        case NOTINLIST:    /* presumably a digit string */
X            upcase(token);
X            ret = token;
X            break;
X
X        default: /* token in list, but is not variable or constant */
X            ret = Convbuf;   /* just to warn the caller */
X            break;
X    }
X    TR_
X    return(ret);
X}
X
X/* translate frombuf number string in frombase radix,
X   to string in tobuf in tobase radix.
X
X   If frombase and tobase are identical no conversion is done;
X   buffer is simply copied.
X   Otherwise, conv_pipe's ibase is set to the frombase radix,
X   conv_pipe's obase is set to tobase, and the frombuf
X   string is executed through conv_pipe.
X
X   If frombase is 0, Lastob is taken as frombase.
X   If frombase is -1, Ibase is taken as frombase.
X   If frombase is 1, frombase is deduced from the first character
X       of frombuf in stack string format.
X
X   If tobuf is ZERO, result goes to Convbuf.  Else tobuf must
X   be at least PIPEMAX long.
X*/
X
Xconv_bc(frombuf, tobuf, frombase, tobase)
Xchar *frombuf, *tobuf;
Xint frombase, tobase;
X{
X    int value, maxchars;
X    int charcount = 0;
X    register char *bptr, *toasc_p;
X    static char *fid = "conv_bc";
X
X    _TR
X    bptr = frombuf;
X    if (tobase == 0)
X        tobase = Ibase;
X    maxchars = strlen(frombuf);
X    if (tobuf == ZERO)
X        tobuf = Convbuf;
X
X    switch (frombase) {
X        case 1:
X            charcount = 1;
X            value = *bptr & 127; /* ascii value of passed radix label */
X            for (toasc_p = Base_str + 16;; toasc_p--) {
X                if (*toasc_p == value) {
X                    frombase = toasc_p - Base_str;
X                    break;
X                }
X            }
X            while ((*++bptr & 127) == ' ') /* get to digit string */
X                ++charcount;
X            break;
X
X        case -1:
X            frombase = Ibase;
X            break;
X
X        case 0:
X            frombase = Lastob;
X            break;
X
X        default:
X            break;
X
X    }
X
X    if (frombase == tobase) {
X        toasc_p = tobuf;
X        while(charcount++ < maxchars)
X            if ((*bptr & 127) != ' ')
X                *toasc_p++ = *bptr++ & 127;
X            else
X                ++bptr;
X        *toasc_p = '\0';
X    }
X    else {
X        sprintf(Mop, "ibase=A;obase=%d;ibase=%d\n", tobase, frombase);
X        toasc_p = &Mop[strlen(Mop)];
X        while(charcount++ < maxchars)
X            *toasc_p++ = *bptr++ & 127;
X        *toasc_p++ = '\n';
X        *toasc_p = '\0';
X        if (write (B_write[1], Mop, strlen(Mop)) == -1)
X            fatal("wait_conv_pipe write");
X        wait_conv_pipe(tobuf);
X    }
X    TR_
X}
X
SHAR_EOF
$TOUCH -am 0221163890 convbase.c &&
chmod 0644 convbase.c ||
echo "restore of convbase.c failed"
set `wc -c convbase.c`;Wc_c=$1
if test "$Wc_c" != "7993"; then
	echo original size 7993, current size $Wc_c
fi
# ============= display.c ==============
echo "x - extracting display.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > display.c &&
X/* display.c */
X/**********************************************************************
X*    File Name     : display.c
X*    Function      : calculator, stack, status window displays of pac
X*    Author        : Istvan Mohos, 1987
X***********************************************************************/
X
X#include "defs.h"
X
X/* display Mainbuf after wait_main_pipe:
X   trim Mainbuf; reformat Mainbuf data in Rebuf, Tmpbuf */
Xdisplay_accum(showflag)
Xint showflag;
X{
X    int zerofill;
X    int dp_at = -1;
X    register int ri;
X    register char *dpptr;
X    char *tpt;
X    int tmpsiz, readsiz;
X    int noint = 0;
X    struct stk_cell *sr = &Stk[0];
X    static char *fid = "display_accum";
X
X    _TR
X    Bc_error = 0;
X    Negative = Too_big = Has_dp = FALSE;
X    e_syntax();
X    e_divby0();
X    e_exponent();
X    e_bcexec();
X
X    if (*Mainbuf == '-')
X        Negative = TRUE;
X
X    dpptr = Mainbuf;
X    if (*dpptr == '.') 
X        noint = 1;
X    ri = 0;
X    while (*dpptr != '\0') { /* wait_pipe changed last newline to \0 */
X        ++ri;
X        if (*dpptr++ == '.') {
X            tpt = dpptr + Precision +1;
X            *tpt = '\0';  /* cut overenthusiastic bc digits */
X            if (tpt == dpptr + strlen(dpptr)) {
X                if (round(Mainbuf, Mainbuf+strlen(Mainbuf))) {
X                    ++dpptr; /* decimal point shifted 1 byte to right */
X                    ++ri;
X                }
X            }
X            Has_dp = TRUE;
X            dp_at = ri;
X        }
X    }
X    if (Has_dp) {               /* trailing zero suppression */
X        while (*--dpptr == '0') {
X            *dpptr = '\0';
X            --ri;
X        }
X        if (*dpptr == '.') {
X            if (noint) {
X                *dpptr = '0';
X                pac_err("underflow");
X            }
X            else {
X                *dpptr = '\0';
X                --ri;
X            }
X            Has_dp = FALSE;
X        }
X    }
X    readsiz = ri;
X
X    if ((strlen(Mainbuf) - Negative - Has_dp) > DIGMAX) {
X        Too_big = TRUE;
X        if (dp_at >= ACCUMAX)
X            Has_dp = FALSE;
X        e_overflow();  /* this error leaves oversize number in buffer */
X        readsiz = DIGMAX + Negative + Has_dp;
X        Mainbuf[readsiz] = '\0';
X    }
X
X    sprintf(sr->cell, "%c %-*.*s", *(Base_str + Obase),
X        STACKMAX-2, STACKMAX-2, Mainbuf);
X
X    if(Justify == JL) {
X        strcpy(Rebuf, Mainbuf);
X        strcat(Rebuf, Sp44);
X        Rebuf[ACCUMAX] = '\0';
X        display(Rebuf);
X    }
X    else if (Justify == JR) {
X        strcpy(Rebuf, Sp44);
X        strcpy(&Rebuf[ACCUMAX - readsiz], Mainbuf);
X        Rebuf[ACCUMAX] = '\0';
X        display(Rebuf);
X    }
X    else {   /* JF */
X        strcpy(Tmpbuf, Mainbuf);
X        if (!Too_big) {
X            if (Has_dp) {
X                strcat(Tmpbuf, Fix32);
X                zerofill = Precision - (readsiz - dp_at);
X                Tmpbuf[readsiz + zerofill] = '\0';
X            }
X            else
X                sprintf(&Tmpbuf[readsiz], ".%.*s", Precision, Fix32);
X        }
X        Tmpbuf[DIGMAX + Negative + Has_dp] = '\0';
X        tmpsiz = strlen(Tmpbuf);
X        strcpy(Rebuf, Sp44);
X        strcpy(&Rebuf[ACCUMAX - tmpsiz], Tmpbuf);
X        display(Rebuf);
X    }
X
X    if ((Stack == ENA) && Painted) {
X        pushstack(1);
X        stack_reg(1, 0);
X    }
X    move(CY=UTOP, CX=ULEFT);
X    if (showflag)
X        pfresh();
X    TR_
X}
X
X/* break up long digit string with spaces, for formatted display */
Xdisplay(source)
Xchar *source;
X{
X    char backward[MYBUF];
X    register ri;
X    register char *from, *to;
X    char *numstart, *frommark, *tomark;
X    int inlen, tail, group, int_digs;
X    static char *fid = "display";
X    
X    _TR
X    if (Format == DISA) {
X        mvaddstr(ACCUM,ULEFT,source);
X        if (Hc != -1 && !Hide) {
X            if ((write(Hc, source, strlen(source))) !=
X                strlen(source))
X                fatal("hardcopy accumulator write");
X            if ((write(Hc, "\n", 1)) != 1)
X                fatal("hardcopy accumulator write");
X        }
X    }
X    else {
X        switch(Obase) {
X        case 2:
X            group = 8;
X            break;
X        case 8:
X        case 10:
X            group = 3;
X            break;
X        case 16:
X        default:
X            group = 4;
X            break;
X        }
X        inlen = strlen(source);
X        from = numstart = source;
X        while ((*numstart == ' ') || (*numstart == '-')) {
X                ++numstart;
X                ++from;
X        }
X        if (*numstart == '.')
X            numstart = ZERO;        /* bc does not prepend 0 before . */
X
X        while (*from != '.' && *from != ' ' && *from != '\0')
X            ++from;                 /* stop on dot, space or null */
X
X        if (from == source + inlen)        /* no fraction */
X            to = &backward[MYBUF - 1];     /* end of source: '\0' */
X        else {
X            tail = source - from + inlen;  /* on (include) dec. point */
X            to = &backward[MYBUF - 1 - tail - (tail-2)/group];
X
X            frommark = from;
X            tomark = to;
X            *to++ = *from++;
X            for (ri = 0; ++ri < tail;) {
X                *to++ = *from++;
X                if ((ri % group == 0) && (*from != ' '))
X                    *to++ = Separator;
X            }
X            from = frommark;
X            to = tomark;
X        }
X        backward[MYBUF - 1] = '\0';
X
X        if (numstart != ZERO) {
X            --to;
X            --from;                        /* back to last int digit */
X            int_digs = from - numstart;    /* one more, really */
X            for (ri = 0; ++ri <= int_digs;) {
X                *to-- = *from--;
X                if (ri % group == 0)
X                    *to-- = Separator;
X            }
X            *to = *from;                   /* first integer digit */
X        }
X        if (Negative)
X            *--to = *--from;
X
X        if (Justify == JL) {
X            strcpy(Tmpbuf, to);
X            strcat(Tmpbuf, Sp44);
X            Tmpbuf[ACCUMAX] = '\0';
X            mvaddstr(ACCUM,ULEFT, Tmpbuf);
X            if (Hc != -1 && !Hide) {
X            if ((write(Hc, Tmpbuf, strlen(Tmpbuf))) !=
X                strlen(Tmpbuf))
X                fatal("hardcopy justified left write");
X            if ((write(Hc, "\n", 1)) != 1)
X                fatal("hardcopy justified left write");
X            }
X        }
X        else {
X            for (ri = from - source + 1; --ri;)
X                *to-- = *from--;
X            *to = *from;          /* to avoid indexing neg. address */
X            to = &backward[MYBUF - 1 - ACCUMAX];
X            mvaddstr(ACCUM,ULEFT, to);
X            if (Hc != -1 && !Hide) {
X                if ((write(Hc, to, strlen(to))) != strlen(to))
X                    fatal("justified right write");
X                if ((write(Hc, "\n", 1)) != 1)
X                    fatal("justified right write");
X            }
X        }
X    }
X    TR_
X}
X
X/* flag values:
X   2)     write to Main pipe, clear_accwin, display_accum.  The user
X          input string is assumed to have completed processing.
X   1)     write to Main pipe, clear_accwin, display_accum only if
X          Show is ENA.  (Some functions may withold the current
X          result from the stack, by temporarily disabling Stack.)
X          The operation always results in a new value from bc, and
X          in the clearing of the input string up to the currently
X          scanned token.
X   0)     write control info to main pipe, redraw Status window.
X          This is a one-way  write to bc, no data is returned in
X          the pipe; the accumulator and Lastob contents stay intact.
X          Error bar under accum does get cleared.
X*/
X
Xshow_result(flag)
Xint flag;
X{
X    int Ubuflen, Controlbuflen;
X    static char *fid = "show_result";
X
X    _TR
X    if (flag) {
X        if ((Ubuflen = strlen(Ubuf)) != 0) {
X            if (!(Ubuflen == 2 && Ubuf[0] == ';')) {
X                if (Ubuf[Ubuflen - 1] != '\n')
X                    Ubuf[Ubuflen++] = '\n';
X
X#ifdef DEBUG
Xfprintf(Dfp, "Ubuf to A_write: %*.*s<<<\n",Ubuflen, Ubuflen, Ubuf);
X#endif
X
X                if (write(A_write[1], Ubuf, Ubuflen) == -1)
X                    fatal("ubuf to main pipe write");
X                clear_accwin();
X                wait_main_pipe();
X
X#ifdef DEBUG
Xfprintf(Dfp, "Mainbuf read: %s<<<\n", Mainbuf);
X#endif
X
X                Lastob = Obase;
X
X                if (Do_conv) {
X                    Titlq[TALYREQ] = ZERO;
X                    show_uconv();
X                    conv_usr();
X                }
X
X                if (Show == ENA || flag > 1)
X                    display_accum(1);
X                else
X                    display_accum(0);
X            }
X            Ubuf[0] = '\0';
X        }
X    }
X    else {
X        if ((Controlbuflen = strlen(Controlbuf)) != 0) {
X            if (Controlbuf[Controlbuflen - 1] != '\n')
X                Controlbuf[Controlbuflen++] = '\n';
X
X#ifdef DEBUG
Xfprintf(Dfp, "Control to A_write: %*.*s<<<\n", Controlbuflen,
X    Controlbuflen, Controlbuf);
X#endif
X
X            if (write(A_write[1], Controlbuf, Controlbuflen) == -1)
X                fatal("controlbuf to main pipe write");
X        }
X        show_stat();
X        Controlbuf[0] = '\0';
X        move(CY=UTOP, CX=ULEFT);
X        pfresh();
X    }
X    TR_
X}
X
Xshow_stat()
X{
X    static char *statstr = "  23456789ABCDEFX";
X    register int cur_y = STATY;
X    int pyp, pxp;
X    static char *fid = "show_stat";
X
X    _TR
X    CYX;
X    standout();
X    mvaddstr(STATY - 1, STATMSG - 1, "    GLOBALS     ");
X    standend();
X
X    move(cur_y++, STATMSG);
X    printw("    ibase %c   " , statstr[Ibase]);
X
X    move(cur_y++, STATMSG);
X    printw("    obase %c   " , statstr[Obase]);
X
X    mvaddstr(cur_y++, STATMSG, (Staybase == ENA) ?  " staybase on  " 
X                                                :  " staybase off " );
X
X
X    move(cur_y++, STATMSG);
X    printw("precision %d  " , Precision);
X
X    mvaddstr(cur_y++, STATMSG, (Autoconv == ENA) ?  " autoconv on  " 
X                                                :  " autoconv off " );
X
X    if (Format == COMMA_)
X        mvaddstr(cur_y++, STATMSG,  "   format ',' " );
X    else if (Format == DISA)
X        mvaddstr(cur_y++, STATMSG,  "   format off " );
X    else /* SPACE_ */
X        mvaddstr(cur_y++, STATMSG,  "   format ' ' " );
X
X    if (Hf == FVER)
X        mvaddstr(cur_y++, STATMSG,  " hardform ver " );
X    else if (Hf == FTER)
X        mvaddstr(cur_y++, STATMSG,  " hardform te  " );
X    else
X        mvaddstr(cur_y++, STATMSG,  " hardform xt  " );
X
X    if (Justify == JF)
X        mvaddstr(cur_y++, STATMSG,  "  justify fix " );
X    else if (Justify == JR)
X        mvaddstr(cur_y++, STATMSG,  "  justify ri  " );
X    else
X        mvaddstr(cur_y++, STATMSG,  "  justify le  " );
X
X    mvaddstr(cur_y++, STATMSG, (Stack == ENA) ?  "    stack on  " 
X                                             :  "    stack off " );
X    mvaddstr(cur_y++, STATMSG, (Autotime == ENA) ?  " autotime on  " 
X                                             :  " autotime off " );
X    Statopts = 0;
X
X    PYX;
X    pfresh();
X    TR_
X}
X
Xshow_param()
X{
X    register int cur_y = STATY;
X    int pyp, pxp;
X    static char *fid = "show_param";
X
X    _TR
X    CYX;
X    standout();
X    mvaddstr(STATY - 1, STATMSG - 1, " STAT  OPTIONS  ");
X    standend();
X
X    mvaddstr(cur_y++, STATMSG, "ib   2 --- 16 ");
X    mvaddstr(cur_y++, STATMSG, "ob   2 --- 16 ");
X    mvaddstr(cur_y++, STATMSG, "sb     off|on ");
X    mvaddstr(cur_y++, STATMSG, "pr   0 --- 32 ");
X    mvaddstr(cur_y++, STATMSG, "au     off|on ");
X    mvaddstr(cur_y++, STATMSG, "fo  sp|off|cm ");
X    mvaddstr(cur_y++, STATMSG, "hf  te|ver|xt ");
X    mvaddstr(cur_y++, STATMSG, "ju  le|fix|ri ");
X    mvaddstr(cur_y++, STATMSG, "st     off|on ");
X    mvaddstr(cur_y++, STATMSG, "at     off|on ");
X
X    Statopts = 1;
X    PYX;
X    pfresh();
X    TR_
X}
X
SHAR_EOF
$TOUCH -am 0221163890 display.c &&
chmod 0644 display.c ||
echo "restore of display.c failed"
set `wc -c display.c`;Wc_c=$1
if test "$Wc_c" != "11737"; then
	echo original size 11737, current size $Wc_c
fi
# ============= error.c ==============
echo "x - extracting error.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > error.c &&
X/* error.c */
X/**********************************************************************
X*    File Name     : error.c
X*    Function      : handling of error messages
X*    Author        : Istvan Mohos, 1987
X***********************************************************************/
X
X#include "defs.h"
X
Xe_syntax()
X{
X    static char *fid = "e_syntax";
X
X    _TR
X    if (strncmp(Mainbuf, "syntax error", 12) == 0) {
X        if (write(A_write[1], "0\n", 2) == -1)
X            fatal("error recovery to main pipe write");
X        /* read back a zero, so next error won't hang bc pipe */
X        wait_main_pipe();
X        standout();
X        move(MSG, MSGLEFT);
X        printw("bc: syntax error                 ");
X        if (Hc != -1 && Hf == FVER)
X            if ((write(Hc, "ERROR: syntax\n", 14)) != 14)
X                fatal("error recovery hardcopy write");
X        standend();
X        Bc_error = E_SYNTAX;
X    }
XTR_
X}
X
Xe_bcexec()
X{
X    static char *fid = "e_bcexec";
X
X    _TR
X    if (strncmp(Mainbuf, "save:args", 9) == 0) {
X        if (write(A_write[1], "0\n", 2) == -1)
X            fatal("error recovery to main pipe write");
X        /* read back a zero, so next error won't hang bc pipe */
X        wait_main_pipe();
X        standout();
X        move(MSG, MSGLEFT);
X        printw("bc: bc calculator failure        ");
X        if (Hc != -1 && Hf == FVER)
X            if ((write(Hc, "ERROR: bcexec\n", 14)) != 14)
X                fatal("error recovery hardcopy write");
X        standend();
X        Bc_error = E_BCEXEC;
X    }
XTR_
X}
X
Xe_divby0()
X{
X    static char *fid = "e_divby0";
X
X    _TR
X    if (strncmp(Mainbuf, "divide by 0", 11) == 0) {
X        Mainbuf[0] = '0';
X        Mainbuf[1] = '\0';
X        standout();
X        move(MSG, MSGLEFT);
X        printw("bc: divide by 0 error            ");
X        if (Hc != -1 && Hf == FVER)
X            if ((write(Hc, "ERROR: divide by 0\n", 19)) != 19)
X                fatal("divby0 hardcopy write");
X        standend();
X        Bc_error = E_DIVBY0;
X    }
XTR_
X}
X
Xe_exponent()
X{
X    static char *fid = "e_exponent";
X
X    _TR
X    if (strncmp(Mainbuf, "exp not an integer", 18) == 0) {
X        Mainbuf[0] = '0';
X        Mainbuf[1] = '\0';
X        standout();
X        move(MSG, MSGLEFT);
X        printw("bc: non-integer exponent error   ");
X        if (Hc != -1 && Hf == FVER)
X            if ((write(Hc, "ERROR: exponent not integer\n", 28)) != 28)
X                fatal("non-int exponent hardcopy write");
X        standend();
X        Bc_error = E_EXPONENT;
X    }
X    else if (strncmp(Mainbuf, "exp too big", 11) == 0) {
X        if (write(A_write[1], "0\n", 2) == -1)
X            fatal("exp2big main pipe write");
X        /* read back a zero, so next error won't hang bc pipe */
X        wait_main_pipe();
X        Mainbuf[0] = '0';
X        Mainbuf[1] = '\0';
X        standout();
X        move(MSG, MSGLEFT);
X        printw("bc: exponent too big error       ");
X        if (Hc != -1 && Hf == FVER)
X            if ((write(Hc, "ERROR: exponent too big\n", 24)) !=  24)
X                fatal("exp2big hardcopy write");
X        standend();
X        Bc_error = E_EXPONENT;
X    }
XTR_
X}
X
Xe_overflow()
X{
X    static char *fid = "e_overflow";
X
X    _TR
X    if (Has_dp == FALSE) { /* don't really care if some digits beyond
X                              the dp fall off, in this case */
X        standout();
X        move(MSG, MSGLEFT);
X        printw(" panel overflow: 32 digits max.  ");
X        if (Hc != -1 && Hf == FVER)
X            if ((write(Hc, "ERROR: overflow\n", 16)) !=  16)
X                fatal("overflow hardcopy write");
X        standend();
X        Bc_error = E_OVERFLOW;
X    }
XTR_
X}
X
Xpac_err(message)
Xchar *message;
X{ 
X    char msg[35];
X    static char *fid = "pac_err";
X
X    _TR
X    strcpy(msg, Sp34); 
X    if (strlen(message) > 22)
X        *(message + 22) = '\0';
X    sprintf(msg, "pac error: %-*s", 22, message);
X    standout();
X    move(MSG, MSGLEFT);
X    printw(msg);
X    standend();
X    pfresh();
XTR_
X}
X
SHAR_EOF
$TOUCH -am 0221163890 error.c &&
chmod 0644 error.c ||
echo "restore of error.c failed"
set `wc -c error.c`;Wc_c=$1
if test "$Wc_c" != "3940"; then
	echo original size 3940, current size $Wc_c
fi
# ============= file.c ==============
echo "x - extracting file.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > file.c &&
X/* file.c */
X/**********************************************************************
X*    File Name     : file.c
X*    Function      : file i/o of pac: rc, hardcopies, debug files
X*    Author        : Istvan Mohos, 1987
X***********************************************************************/
X
X#include "defs.h"
X#define FILEMAP
X#include "maps.h"
X#undef FILEMAP
X
X#define RCMIN  (STACKDEEP * (STACKMAX + 1) + 53) /* minimum count */
Xread_rc()
X{
X    char rcbuf[PIPEMAX];
X    register char *rc = rcbuf;
X    static char *fid = "read_rc";
X
X    _TR
X    if (read(Rcfd, rc, RCMIN) < RCMIN) {
X        mvaddstr(2,4,"Rcerr after RCMIN");
X        pfresh();
X        Rcerr = TRUE;
X        TR_
X        return;
X    }
X    if ((Format = *rc++ -48)!=COMMA_ && Format!=SPACE_ && Format!=DISA)
X        Format = FORM_DFLT;
X    (Format == COMMA_) ? (Separator = ',') : (Separator = ' ');
X
X    if ((Hf = *rc++ -48) != FVER && Hf != FTER && Hf != FXTER)
X        Hf = HF_DFLT;
X    if ((Ibase = *rc++ -48) < 2 || Ibase > 16)
X        Ibase = IB_DFLT;
X    if ((Justify = *rc++ -48) != JL && Justify != JF && Justify != JR)
X        Justify = JUS_DFLT;
X    if ((Obase = *rc++ -48) < 2 || Obase > 16)
X        Obase = OB_DFLT;
X    if ((Precision = *rc++ -48) < 0 || Precision > 32)
X        Precision = PREC_DFLT;
X    if ((Autotime = *rc++ -48) != ENA && Autotime != DISA)
X        Autotime = DISA;
X    if ((Stack = *rc++ -48) != ENA && Stack != DISA)
X        Stack = STACK_DFLT;
X    if ((Staybase = *rc++ -48) != ENA && Staybase != DISA)
X        Staybase = SB_DFLT;
X    if ((Convcount = atoi(rc)) > 255 || Convcount < CONVCOUNT) {
X        mvaddstr(2,4,"Rcerr at Convcount");
X        pfresh();
X        Rcerr = TRUE;
X        TR_
X        return;
X    }
X    rc += 4;
X    if ((Convsel = atoi(rc)) < 0 || Convsel > Convcount -1)
X        Convsel = CONVSEL;
X    rc += 4;
X    if ((Convhsiz = atoi(rc)) < 1) {
X        mvaddstr(2,4,"Rcerr after Convhsiz");
X        pfresh();
X        Rcerr = TRUE;
X        TR_
X        return;
X    }
X    rc += 6;
X    if ((Amt = atof(rc)) < 0.)
X        Amt = 0.;
X    rc += 14;
X    if ((Years = atof(rc)) < 0.)
X        Years = 0.;
X    rc += 8;
X    if ((Rate = atof(rc)) < 0.)
X        Rate = 0.;
X    rc += 8;
X
X    fill_stack(rc);
X
X    if ((Convhom = malloc(Convhsiz)) == ZERO)
X        fatal("malloc error at read_rc");
X
X    if (read(Rcfd, Convhom, (int)Convhsiz) != Convhsiz) {
X        mvaddstr(2,4,"Rcerr after Convhom");
X        pfresh();
X        Rcerr = TRUE;
X        TR_
X        return;
X    }
X
X    for (rc = Convhom + Convhsiz; --rc > Convhom;)
X        if (*rc == '\n')
X            *rc = 0;
X 
X    realign_conv();
X    TR_
X}
X
Xwrite_rc()
X{
X    char rcbuf[PIPEMAX];
X    register char *rc = rcbuf;
X    static char *fid = "write_rc";
X
X    _TR
X    if (Home != ZERO && !Dontsave) {
X        if ((Rcfd = open(Rcfile, O_WRONLY | O_CREAT, 0600)) != -1) {
X
X            *rc++ = Format +48;
X            *rc++ = Hf +48;
X            *rc++ = Ibase +48;
X            *rc++ = Justify +48;
X            *rc++ = Obase +48;
X            *rc++ = Precision +48;
X            *rc++ = Autotime +48;
X            *rc++ = Stack +48;
X            *rc++ = Staybase +48;
X            sprintf(rc, "%3d;%3d;%5d\n", Convcount, Convsel, Convhsiz);
X            rc += 14;
X            sprintf(rc, "%13.2f", Amt);
X            rc += 13;
X            *rc++ = ';'; /* printf too generous on overflow*/
X            sprintf(rc, "%7.3f", Years);
X            rc += 7;
X            *rc++ = ';';
X            sprintf(rc, "%7.3f", Rate);
X            rc += 7;
X            *rc++ = '\n';
X
X            save_stack(rc, 0);
X
X            if ((write(Rcfd, rcbuf, RCMIN)) != RCMIN)
X                fatal("pacrc stack write");
X
X            for (rc = Convhom + Convhsiz; --rc > Convhom;)
X                if (*rc == '\0')
X                    *rc = '\n';
X            if ((write(Rcfd, Convhom, (int)Convhsiz)) != (int)Convhsiz)
X                fatal("pacrc conv write");
X
X            close(Rcfd);
X       }
X    }
X    TR_
X}
X
X#ifdef DESIGN
Xread_scr(name)        /* read screen image from named file */
Xchar *name;
X{
X    FILE *fp;
X    register rx, ry;
X    static char *fid = "read_scr";
X
X    _TR
X    if ((fp = fopen(name, "r")) != NULL) {
X        for (ry = 0; ry < LINES; ry++)
X            for (rx=0; rx < COLS-1; rx++)
X                stdscr->_y[ry][rx] = fgetc(fp);
X        fclose(fp);
X    }
X    TR_
X}
X
Xwrite_scr(name, rf)
Xchar *name;
Xint rf;
X{
X    FILE *fp;
X    register rx, ry;
X    static char *fid = "write_scr";
X
X    _TR
X    if ((fp = fopen(name, "w")) == NULL)
X        Status = 1, fatal("write image");
X    if (rf)
X        for (ry = 0; ry < LINES; ry++)
X            for (rx=0; rx < COLS-1; rx++)
X                putc(stdscr->_y[ry][rx] & 0377, fp);
X    else
X        for (ry = 0; ry < LINES; ry++) {
X            for (rx=0; rx < COLS-1; rx++)
X                putc(stdscr->_y[ry][rx] & 127, fp);
X            putc('\n', fp);
X        }
X    fclose(fp);
X    TR_
X}
X#endif
X
Xhard(fnum)
Xint fnum;
X{
X    int newlev;
X    int pyp, pxp;
X    int *whichfile, *whichfd;
X    char *np;
X    char *whichname;
X    char namebuf[TITSIZ + 1];
X    char spaceless[TITSIZ + 1];
X    static char *fid = "hard";
X
X    _TR
X    if (fnum) {
X        whichname = Totname;
X        whichfd = &Tc;
X        if (*(whichfile = &Totcopy) == ENA)
X            newlev = TOTLREQ;
X        else if (*whichfile == AP)
X            newlev = TAPPREQ;
X        else {
X            newlev = TALYREQ;
X            Basq[TOTLREQ] = ZERO;
X            Basq[TAPPREQ] = ZERO;
X        }
X    }
X    else {
X        whichname = Hardname;
X        whichfd = &Hc;
X        if (*(whichfile = &Hardcopy) == ENA)
X            newlev = FILEREQ;
X        else if (*whichfile == AP)
X            newlev = POSTREQ;
X        else {
X            newlev = 0;
X            Basq[FILEREQ] = ZERO;
X            Basq[POSTREQ] = ZERO;
X        }
X    }
X    Basq[newlev] = Bb[newlev];
X    Basq[EDITREQ] = Bb[newlev];
X    CYX;  /* to save the caller's coordinates */
X    update();  /* this returns to the original coordinates,
X                  but does'nt pfresh */
X    
X    if (*whichfile == ENA || *whichfile == AP) {
X
Xredo:
X
X        ledit(namebuf, f_ed_map, BOT, FBOUND, RBOUND, 1, 1, 0);
X
X        if (strlen(namebuf) == 0) {
X            strcpy(spaceless, whichname);
X            for (np = spaceless; *np > 32; np++);
X            *np = '\0';
X            standout();
X            mvaddstr(BOT, FBOUND, whichname);
X            standend();
X            pfresh();
X        }
X        else {
X            strcpy(whichname, namebuf);
X            strcpy(spaceless, namebuf);
X        }
X
X        if (*whichfile == ENA) {
X            if ((*whichfd = open(spaceless,
X            O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) {
X                standout();
X                mvaddstr(BOT, ULEFT, "can't access:");
X                standend();
X                pfresh();
X                goto redo;
X            }
X        }
X        else if ((*whichfd = open(spaceless,
X            O_WRONLY | O_APPEND | O_CREAT, 0644)) == -1) {
X                standout();
X                mvaddstr(BOT, ULEFT, "can't access:");
X                standend();
X                pfresh();
X                goto redo;
X        }
X        /* make a copy of name in alternate buffer also */
X        if (*whichfile == AP) {
X            strcpy(Bb[newlev - 1] + BUFSTOP, whichname);
X            rev_clear(Bb[newlev - 1] + TITSIZ);
X        }
X        else {
X            strcpy(Bb[newlev + 1] + BUFSTOP, whichname);
X            rev_clear(Bb[newlev + 1] + TITSIZ);
X        }
X        strcpy(Bb[newlev] + BUFSTOP, whichname);
X        rev_clear(Bb[newlev] + TITSIZ);
X        Basq[EDITREQ] = ZERO;
X    }
X    PYX;
X    update();
X    pfresh();
X    TR_
X}
SHAR_EOF
$TOUCH -am 0221163890 file.c &&
chmod 0644 file.c ||
echo "restore of file.c failed"
set `wc -c file.c`;Wc_c=$1
if test "$Wc_c" != "7596"; then
	echo original size 7596, current size $Wc_c
fi
echo "End of part 3, continue with part 4"
exit 0