Annotation of 43BSD/contrib/B/src/bint/b3scr.c, revision 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.