Annotation of 43BSD/contrib/B/src/bint/b3scr.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
                      2: 
                      3: /*
                      4:   $Header: b3scr.c,v 1.4 85/08/22 16:58:54 timo Exp $
                      5: */
                      6: 
                      7: /* B input/output handling */
                      8: 
                      9: #include "b.h"
                     10: #include "b0fea.h"
                     11: #include "b1mem.h"
                     12: #include "b1obj.h"
                     13: #include "b0con.h" /*for CLEAR_EOF*/
                     14: #include "b2nod.h"
                     15: #include "b2syn.h"
                     16: #include "b2par.h"
                     17: #include "b3scr.h"
                     18: #include "b3err.h"
                     19: #include "b3fil.h"
                     20: #include "b3typ.h"
                     21: #include "b3env.h"
                     22: #include "b3sem.h"
                     23: #include "b3int.h"
                     24: #ifdef SETJMP
                     25: #include <setjmp.h>
                     26: #endif
                     27: 
                     28: Visible bool interactive;
                     29: Visible bool rd_interactive;
                     30: Visible value iname= Vnil;     /* input name */
                     31: Visible bool filtered= No;
                     32: Visible bool outeractive;
                     33: #ifdef SETJMP
                     34: Visible bool awaiting_input= No;
                     35: Visible jmp_buf read_interrupt;
                     36: #endif
                     37: Visible bool at_nwl= Yes;      /*Yes if currently at the start of an output line*/
                     38: Hidden bool woa, wnwl;         /*was outeractive, was at_nwl */
                     39: Hidden bool last_was_text= No; /*Yes if last value written was a text*/
                     40: 
                     41: Visible bool Eof;
                     42: FILE *ofile= stdout;
                     43: FILE *ifile;           /* input file */
                     44: FILE *sv_ifile;                /* copy of ifile for restoring after reading unit */
                     45: 
                     46: /******************************* Output *******************************/
                     47: 
                     48: #ifndef INTEGRATION
                     49: 
                     50: Hidden Procedure putch(c) char c; {
                     51:        if (still_ok) {
                     52:                putc(c, ofile);
                     53:                if (c == '\n') at_nwl= Yes;
                     54:                else at_nwl= No;
                     55:        }
                     56: }
                     57: 
                     58: #else
                     59: 
                     60: Hidden int ocol;       /* Current output column */
                     61: 
                     62: Hidden Procedure putch(c) char c; {
                     63:        if (still_ok) {
                     64:                putc(c, ofile);
                     65:                if (c == '\n') { at_nwl= Yes; ocol= 0; }
                     66:                else {
                     67:                        if (at_nwl) { ocol= 0; at_nwl= No;}
                     68:                        ++ocol;
                     69:                }
                     70:        }
                     71: }
                     72: 
                     73: #endif
                     74: 
                     75: Visible Procedure newline() {
                     76:        putch('\n');
                     77:        fflush(stdout);
                     78: }
                     79: 
                     80: Hidden Procedure line() {
                     81:        if (!at_nwl) newline();
                     82: }
                     83: 
                     84: Visible Procedure wri_space() {
                     85:        putch(' ');
                     86: }
                     87: 
                     88: Visible Procedure writ(v) value v; {
                     89:        wri(v, Yes, Yes, No);
                     90:        fflush(stdout);
                     91: }
                     92: 
                     93: #define Putch_sp() {if (!perm) putch(' ');}
                     94: 
                     95: Hidden int intsize(v) value v; {
                     96:        value s= size(v); int len=0;
                     97:        if (large(s)) error(MESS(3800, "value too big to output"));
                     98:        else len= intval(s);
                     99:        release(s);
                    100:        return len;
                    101: }
                    102: 
                    103: Hidden bool lwt;
                    104: 
                    105: Visible Procedure wri(v, coll, outer, perm) value v; bool coll, outer, perm; {
                    106:        if (outer && !at_nwl && (!Is_text(v) || !last_was_text)
                    107:                  && (!Is_compound(v) || !coll)) putch(' ');
                    108:        lwt= No;
                    109:        if (Is_number(v)) {
                    110:                if (perm) printnum(ofile, v);
                    111:                else {
                    112:                        string cp= convnum(v);
                    113:                        while(*cp && still_ok) putch(*cp++);
                    114:                }
                    115:        } else if (Is_text(v)) {
                    116: #ifndef INTEGRATION
                    117:                wrtext(putch, v, outer ? '\0' : '"');
                    118: #else
                    119:                value ch; char c; int k, len= Length(v);
                    120: #define QUOTE '"'
                    121:                if (!outer) putch(QUOTE);
                    122:                for (k=0; k<len && still_ok; k++) {
                    123:                        ch= thof(k+1, v);
                    124:                        putch(c= charval(ch));
                    125:                        if (!outer && (c == QUOTE || c == '`'))
                    126:                                putch(c);
                    127:                        release(ch);
                    128:                }
                    129:                if (!outer) putch(QUOTE);
                    130: #endif
                    131:                lwt= outer;
                    132:        } else if (Is_compound(v)) {
                    133:                intlet k, len= Nfields(v);
                    134:                outer&= coll;
                    135:                if (!coll) putch('(');
                    136:                for (k=0; k<len && still_ok; k++) {
                    137:                        wri(*Field(v, k), No, outer, perm);
                    138:                        if (!Lastfield(k)) {
                    139:                                if (!outer){
                    140:                                        putch(',');
                    141:                                        Putch_sp();
                    142:                                }
                    143:                        }
                    144:                }
                    145:                if (!coll) putch(')');
                    146:        } else if (Is_list(v) || Is_ELT(v)) {
                    147:                value ve; int k, len= intsize(v);
                    148:                putch('{');
                    149:                for (k=0; k<len && still_ok; k++) {
                    150:                        wri(ve= thof(k+1, v), No, No, perm);
                    151:                        release(ve);
                    152:                        if (!Last(k)) {
                    153:                                putch(';');
                    154:                                Putch_sp();
                    155:                        }
                    156:                }
                    157:                putch('}');
                    158:        } else if (Is_table(v)) {
                    159:                int k, len= intsize(v);
                    160:                putch('{');
                    161:                for (k=0; k<len && still_ok; k++) {
                    162:                        putch('['); wri(*key(v, k), Yes, No, perm);
                    163:                        putch(']'); putch(':'); Putch_sp();
                    164:                        wri(*assoc(v, k), No, No, perm);
                    165:                        if (!Last(k)) {
                    166:                                putch(';');
                    167:                                Putch_sp();
                    168:                        }
                    169:                }
                    170:                putch('}');
                    171:        } else {
                    172:                if (bugs || testing) { putch('?'); putch(Type(v)); putch('?'); }
                    173:                else syserr(MESS(3801, "writing value of unknown type"));
                    174:        }
                    175:        last_was_text= lwt;
                    176: #ifdef IBMPC
                    177:        if (interrupted) clearerr(ofile);
                    178: #endif
                    179: }
                    180: 
                    181: /***************************** Input ****************************************/
                    182: 
                    183: Hidden char cmbuf[CMBUFSIZE]; /* for commands */
                    184: Hidden char rdbuf[RDBUFSIZE]; /* for READ EG/RAW */
                    185: 
                    186: #ifndef INTEGRATION
                    187: Visible string cmd_prompt= ">>> "; /* commands  */
                    188: Visible string eg_prompt=  "?\b";  /* READ EG   */
                    189: Visible string raw_prompt= "?\b";  /* READ RAW  */
                    190: Visible string qn_prompt=  "?\b";  /* questions */
                    191: #else
                    192: Hidden literal cmd_prompt= '>'; /* commands  */
                    193: Hidden literal eg_prompt=  'E';  /* READ EG   */
                    194: Hidden literal raw_prompt= 'R';  /* READ RAW  */
                    195: Hidden literal qn_prompt= 'Y';  /* questions */
                    196: Visible literal unit_prompt= ':'; /* units */
                    197: Visible literal tar_prompt= '='; /* targets */
                    198: #endif
                    199: 
                    200: /* Read a line; EOF only allowed if not interactive, in which case eof set */
                    201: /* Returns the line input                                                  */
                    202: /* This is the only place where a long jump is necessary                   */
                    203: /* In other places, interrupts are just like procedure calls, and checks   */
                    204: /* of still_ok and interrupted suffice: eventually the stack unwinds to the*/
                    205: /* main loop in imm_command(). Here though, an interrupt must actually     */
                    206: /* terminate the read. Hence the bool awaiting_input indicating if the     */
                    207: /* long jump is necessary or not                                           */
                    208: 
                    209: #ifndef INTEGRATION
                    210: 
                    211: Hidden txptr read_line(should_prompt, prompt, cmd, eof, eof_message)
                    212:  bool should_prompt, cmd, *eof; string prompt, eof_message; {
                    213:        txptr buf, rp, bufend; intlet k; bool got= No;
                    214:        FILE *f;
                    215:        *eof= No;
                    216:        if (cmd) { buf= cmbuf; bufend= &cmbuf[CMBUFSIZE-2]; }
                    217:        else     { buf= rdbuf; bufend= &rdbuf[RDBUFSIZE-2]; }
                    218: #ifdef SETJMP
                    219:        if (setjmp(read_interrupt) != 0) {
                    220:                awaiting_input= No;
                    221:                return buf;
                    222:        }
                    223: #endif
                    224:        while (!got) {
                    225:                rp= buf;
                    226: #ifdef SETJMP
                    227:                awaiting_input= Yes;
                    228: #endif
                    229:                if (should_prompt) {
                    230:                        if (cmd) {
                    231:                                if (outeractive) {
                    232:                                        line();
                    233:                                        at_nwl= No;
                    234:                                }
                    235:                        }
                    236:                        fprintf(stderr, prompt); fflush(stderr);
                    237:                        f= stdin;
                    238:                } else {
                    239:                        f= ifile;
                    240:                }
                    241:                while ((k= getc(f)) != EOF && k != '\n') {
                    242:                        *rp++= k;
                    243:                        if (rp >= bufend) syserr(MESS(3802, "buffer overflow"));
                    244:                }
                    245: #ifdef SETJMP
                    246:                awaiting_input= No;
                    247: #endif
                    248:                got= Yes; *rp++= '\n'; *rp= '\0';
                    249:                if (k == EOF) {
                    250:                        if (should_prompt) {
                    251:                                if (filtered) {
                    252:                                        bye(0); /*Editor has died*/
                    253:                                } else {
                    254:                                        fprintf(stderr, "\r*** %s\n", eof_message);
                    255:                                        CLEAR_EOF;
                    256:                                        if (outeractive) at_nwl= Yes;
                    257:                                        got= No;
                    258:                                }
                    259:                        } else *eof= Yes;
                    260:                }
                    261:        }
                    262:        if (should_prompt && outeractive && k == '\n') at_nwl= Yes;
                    263:        return buf;
                    264: }
                    265: 
                    266: #else INTEGRATION
                    267: 
                    268: Hidden intlet
                    269: rd_fileline(nbuf, file, nbufend)
                    270:        string nbuf, nbufend;
                    271:        FILE *file;
                    272: {
                    273:        intlet k;
                    274:        while ((k= getc(file)) != EOF && k != '\n') {
                    275:                *nbuf++= k;
                    276:                if (nbuf >= nbufend)
                    277:                        syserr(MESS(3803, "buffer overflow rd_fileline()"));
                    278:        }
                    279:        *nbuf++= '\n'; *nbuf= '\0';
                    280:        return k;
                    281: }
                    282: 
                    283: Hidden intlet
                    284: rd_bufline(nbuf, obuf, nbufend)
                    285:        string nbuf, *obuf, nbufend;
                    286: {
                    287:        while (**obuf && **obuf != '\n') {
                    288:                *nbuf++= **obuf; ++*obuf;
                    289:                if (nbuf >= nbufend)
                    290:                        syserr(MESS(3804, "buffer overflow rd_bufline()"));
                    291:        }
                    292:        *nbuf++= '\n'; *nbuf= '\0';
                    293:        if (**obuf)  { ++*obuf; return '\n';}
                    294:        else return EOF;
                    295: }
                    296: 
                    297: Hidden string edcmdbuf;
                    298: 
                    299: Hidden txptr
                    300: read_line(should_prompt, prompt, cmd, eof, eof_message)
                    301:        bool should_prompt, cmd, *eof; literal prompt; string eof_message;
                    302: {
                    303:        txptr buf, rp, bufend; intlet k, indent= 0; bool got= No;
                    304:        static string pedcmdbuf;
                    305:        if (prompt == eg_prompt || prompt == raw_prompt) indent= ocol;
                    306:        *eof= No;
                    307:        if (cmd) { buf= cmbuf; bufend= &cmbuf[CMBUFSIZE-2]; }
                    308:        else     { buf= rdbuf; bufend= &rdbuf[RDBUFSIZE-2]; }
                    309: #ifdef SETJMP
                    310:        if (setjmp(read_interrupt) != 0) {
                    311:                awaiting_input= No;
                    312:                return buf;
                    313:        }
                    314: #endif
                    315:        while (!got) {
                    316:                rp= buf; got= Yes;
                    317: #ifdef SETJMP
                    318:                awaiting_input= Yes;
                    319: #endif
                    320:                if (!should_prompt) {
                    321:                        k= rd_fileline(rp, ifile, bufend);
                    322:                        if (k == EOF) *eof= Yes;
                    323:                } else {
                    324:                        if (!edcmdbuf) {
                    325:                                if (cmd && outeractive) { line(); at_nwl= No; }
                    326:                                btop(&edcmdbuf, 0, prompt, indent);
                    327:                                pedcmdbuf= edcmdbuf;
                    328:                        }
                    329:                        k= rd_bufline(rp, &pedcmdbuf, bufend);
                    330:                        if (k == EOF) {
                    331:                                freemem((ptr) edcmdbuf);
                    332:                                edcmdbuf= (string) NULL;
                    333:                                if (prompt != '>') got= No;
                    334:                        } 
                    335:                }
                    336: #ifdef SETJMP
                    337:                awaiting_input= No;
                    338: #endif
                    339:        }
                    340: 
                    341:        if (should_prompt && outeractive && k == '\n') at_nwl= Yes;
                    342:        return buf;
                    343: }
                    344: 
                    345: #endif INTEGRATION
                    346: 
                    347: /* Rather over-fancy routine to ask the user a question */
                    348: /* Will anybody discover that you're only given 4 chances? */
                    349: 
                    350: Hidden char USE_YES_OR_NO[]=
                    351:  "Answer with yes or no (or use interrupt to duck the question)";
                    352: 
                    353: Hidden char LAST_CHANCE[]=
                    354:  "This is your last chance. Take it. I really don't know what you want.\n\
                    355:     So answer the question";
                    356: 
                    357: Hidden char NO_THEN[]=
                    358:  "Well, I shall assume that your refusal to answer the question means no!";
                    359: 
                    360: Visible bool is_intended(m) string m; {
                    361:        char answer; intlet try; txptr tp; bool eof;
                    362:        if (!interactive) return Yes;
                    363:        if (outeractive) line();
                    364:        for (try= 1; try<=4; try++){
                    365:                if (try == 1 || try == 3) fprintf(stderr, "*** %s\n", m);
                    366:                tp= read_line(Yes, qn_prompt, No, &eof, USE_YES_OR_NO);
                    367:                skipsp(&tp);
                    368:                answer= Char(tp);
                    369:                if (answer == 'y' || answer == 'Y') return Yes;
                    370:                if (answer == 'n' || answer == 'N') return No;
                    371:                if (outeractive) line();
                    372:                fprintf(stderr, "*** %s\n",
                    373:                        try == 1 ? "Please answer with yes or no" :
                    374:                        try == 2 ? "Just yes or no, please" :
                    375:                        try == 3 ? LAST_CHANCE :
                    376:                        NO_THEN);
                    377:        } /* end for */
                    378:        return No;
                    379: }
                    380: 
                    381: /* Read_eg uses evaluation but it shouldn't.
                    382:    Wait for a more general mechanism. */
                    383: 
                    384: Visible Procedure read_eg(l, t) loc l; btype t; {
                    385:        context c; parsetree code;
                    386:        parsetree r= NilTree; value rv= Vnil; btype rt= Vnil;
                    387:        envtab svprmnvtab= Vnil;
                    388:        txptr fcol_save= first_col, tx_save= tx;
                    389:        do {
                    390:                still_ok= Yes;
                    391:                sv_context(&c);
                    392:                if (cntxt != In_read) {
                    393:                        release(read_context.uname);
                    394:                        sv_context(&read_context);
                    395:                }
                    396:                svprmnvtab= prmnvtab == Vnil ? Vnil : prmnv->tab;
                    397:                /* save scratch-pad copy because of following setprmnv() */
                    398:                setprmnv();
                    399:                cntxt= In_read;
                    400:                first_col= tx= read_line(rd_interactive, eg_prompt, No,
                    401:                        &Eof, "use interrupt to abort READ command");
                    402:                if (still_ok && Eof)
                    403:                        error(MESS(3805, "End of file encountered during READ command"));
                    404:                if (!rd_interactive) f_lino++;
                    405:                if (still_ok) {
                    406:                        findceol();
                    407:                        r= expr(ceol);
                    408:                        if (still_ok) fix_nodes(&r, &code);
                    409:                        rv= evalthread(code); release(r);
                    410:                        rt= still_ok ? valtype(rv) : Vnil;
                    411:                        if (svprmnvtab != Vnil) {
                    412:                                prmnvtab= prmnv->tab;
                    413:                                prmnv->tab= svprmnvtab;
                    414:                        }
                    415:                        set_context(&c);
                    416:                        if (still_ok) must_agree(t, rt,
                    417:        MESS(3806, "type of expression does not agree with that of EG sample"));
                    418:                        release(rt);
                    419:                }
                    420:                if (!still_ok && rd_interactive && !interrupted)
                    421:                        fprintf(stderr, "*** Please try again\n");
                    422:        } while (!interrupted && !still_ok && rd_interactive);
                    423:        if (still_ok) put(rv, l);
                    424:        first_col= fcol_save;
                    425:        tx= tx_save;
                    426:        release(rv);
                    427: }
                    428: 
                    429: Visible Procedure read_raw(l) loc l; {
                    430:        value r; bool eof;
                    431:        txptr line= read_line(rd_interactive, raw_prompt, No, &eof, 
                    432:                        "use interrupt to abort READ t RAW");
                    433:        if (still_ok && eof) error(MESS(3807, "End of file encountered during READ t RAW"));
                    434:        if (!rd_interactive) f_lino++;
                    435:        if (still_ok) {
                    436:                txptr rp= line;
                    437:                while (*rp != '\n') rp++;
                    438:                *rp= '\0';
                    439:                r= mk_text(line);
                    440:                put(r, l);
                    441:                release(r);
                    442:        }
                    443: }
                    444: 
                    445: Visible txptr getline() {
                    446:        bool should_prompt=
                    447:                interactive && sv_ifile == ifile;
                    448:        return read_line(should_prompt, cmd_prompt, Yes, &Eof,
                    449:                        "use QUIT to end session");
                    450: }
                    451: 
                    452: /******************************* Files ******************************/
                    453: 
                    454: Visible Procedure redirect(of) FILE *of; {
                    455:        ofile= of;
                    456:        if (of == stdout) {
                    457:                outeractive= woa;
                    458:                at_nwl= wnwl;
                    459:        } else {
                    460:                woa= outeractive; outeractive= No;
                    461:                wnwl= at_nwl; at_nwl= Yes;
                    462:        }
                    463: }
                    464: 
                    465: Visible Procedure vs_ifile() {
                    466:        ifile= sv_ifile;
                    467: }
                    468: 
                    469: Visible Procedure re_screen() {
                    470:        sv_ifile= ifile;
                    471:        interactive= f_interactive(ifile) || (ifile == stdin && filtered);
                    472:        Eof= No;
                    473: }
                    474: 
                    475: /* initscr is a reserved name of CURSES */
                    476: Visible Procedure init_scr() {
                    477:        outeractive= f_interactive(stdout) || filtered;
                    478:        rd_interactive= f_interactive(stdin) || filtered;
                    479:        rdbuf[0]= '\n'; tx= rdbuf;
                    480: }
                    481: 
                    482: Visible Procedure
                    483: endscr()
                    484: {
                    485: #ifdef INTEGRATION
                    486:        if (edcmdbuf) {
                    487:                freemem((ptr) edcmdbuf);
                    488:                edcmdbuf= (string) NULL;
                    489:        }
                    490: #endif
                    491: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.