Annotation of 43BSDTahoe/new/B/src/bint/b3err.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
                      2: 
                      3: /*
                      4:   $Header: b3err.c,v 1.4 85/08/22 16:57:50 timo Exp $
                      5: */
                      6: 
                      7: /* B error message handling */
                      8: 
                      9: /* There are two kinds of errors:
                     10:        1) parsing, when the line in error is in a buffer
                     11:        2) execution, when the line in error is a parse-tree, and must
                     12:           therefore be reconstructed.
                     13: */
                     14: 
                     15: /* All error messages are collected in a file, both to save data space
                     16:    and to ease translation to other languages. The English version
                     17:    of the database can be recreated from the program sources by scanning
                     18:    for the pattern "MESS(".  This is a macro whose first argument is
                     19:    the message number and whose second number is the message string;
                     20:    this macro expands to only the message number which is passed to
                     21:    the error routines. The error routines then dig the message from
                     22:    the error message file, or just print the number if the file can't be
                     23:    opened.  There is also a way to pass a message that is determined
                     24:    at runtime.
                     25: */
                     26: 
                     27: #include "b.h"
                     28: #include "b0fea.h"
                     29: #include "b0fil.h"
                     30: #include "b1obj.h"
                     31: #include "b2syn.h"
                     32: #include "b3env.h"
                     33: #include "b3fil.h"
                     34: #include "b3err.h"
                     35: #include "b3scr.h"
                     36: #include "b3sig.h"
                     37: #include "b3sou.h"
                     38: 
                     39: Visible bool still_ok, interrupted;
                     40: 
                     41: Visible parsetree curline= Vnil;
                     42: Visible value curlino;
                     43: Visible context how_context, act_context;
                     44: 
                     45: FILE *errfile; /* The first thing a visible routine must do is set this */
                     46:                /* usually by calling line()                             */
                     47: 
                     48: #define Interactive (errfile == stderr)
                     49: 
                     50: /*********************************************************************/
                     51: 
                     52: /* While we are reading the Messages file, we build an index.
                     53:    probe[k] contains the first message number found in block k.
                     54:    blocks are BUFSIZ in size. */
                     55: 
                     56: #define FILESIZE 12916 /* Approximated current size of Messages file */
                     57: #define MAXPROBE (10 + FILESIZE/BUFSIZ) /* Allow some growth */
                     58: 
                     59: Hidden short probe[MAXPROBE];
                     60: Hidden int nprobes= 1;
                     61: 
                     62: Hidden FILE *messfp;
                     63: Hidden string savedmess;
                     64: 
                     65: Visible int MESSMAKE(mess) string mess; {
                     66:        savedmess= mess;
                     67:        return -1;
                     68: }
                     69: 
                     70: Visible string getmess(nr) int nr; {
                     71:        int last, c; char *cp= NULL;
                     72:        static char buf[80]; bool new; int block; long ftell();
                     73:        char *filename;
                     74:        if (nr == 0) return "";
                     75:        if (nr < 0) { return savedmess; }
                     76:        if (messfp == NULL)
                     77:                messfp= fopen(messfile, "r");
                     78:        if (messfp) {
                     79:                for (block= nprobes-1; block > 0; --block) {
                     80:                        if (probe[block] <= nr)
                     81:                                break;
                     82:                }
                     83:                new= block == nprobes-1;
                     84:                fseek(messfp, (long)block*BUFSIZ, 0);
                     85:                last= 0;
                     86:                while (last < nr) {
                     87:                        if (new) block= ftell(messfp) / BUFSIZ;
                     88:                        if (fgets(buf, sizeof buf, messfp) == NULL) break;
                     89:                        last= atoi(buf);
                     90:                        if (last <= 0)
                     91:                                continue;
                     92:                        if (new && block >= nprobes && nprobes < MAXPROBE) {
                     93:                                probe[block]= last;
                     94:                                nprobes= block+1;
                     95:                        }
                     96:                }
                     97:                if (last == nr) {
                     98:                        cp= index(buf, '\n');
                     99:                        if (cp != NULL) *cp = '\0'; /* strip terminating \n */
                    100:                        cp= buf;
                    101:                        cp= index(buf, '\t');
                    102:                        if (cp != NULL) return cp+1;
                    103:                }
                    104:        }
                    105:        sprintf(buf, " (error %d) ", nr);
                    106:        return buf;
                    107: }
                    108: 
                    109: Hidden Procedure prmess(nr) int nr; {
                    110:        errmess(getmess(nr));
                    111: }
                    112: 
                    113: /*********************************************************************/
                    114: 
                    115: Hidden Procedure putch(c) char c; {
                    116:        putc(c, errfile);
                    117: }
                    118: 
                    119: Hidden Procedure line() {
                    120: #ifdef EXT_COMMAND
                    121:        e_done();
                    122: #endif
                    123:        fflush(stdout);
                    124:        if (cntxt == In_read) {
                    125:                if (rd_interactive) {
                    126:                        errfile= stderr; at_nwl= Yes;
                    127:                } else errfile= stdout;
                    128:        } else if (interactive) errfile= stderr;
                    129:               else errfile= stdout;
                    130:        if (!at_nwl) putch('\n');
                    131:        at_nwl= Yes;
                    132: }
                    133: 
                    134: Hidden Procedure errmess(m) string m; {
                    135:        fputs(m, errfile);
                    136: }
                    137: 
                    138: #ifdef NOT_USED
                    139: Hidden Procedure core_dump() {
                    140:        errmess("*** Core-dump for inspection purposes: ");
                    141:        fflush(stdout);
                    142:        dump();
                    143: }
                    144: #endif
                    145: 
                    146: Hidden Procedure prname(name) value name; {
                    147:        if (Is_text(name)) {
                    148:                still_ok= Yes;
                    149:                writ(name);
                    150:                still_ok= No;
                    151:        }
                    152: }
                    153: 
                    154: Visible value erruname= Vnil;
                    155: Visible intlet errlino= 0;
                    156: 
                    157: Hidden intlet pr_line(at) bool at; {
                    158:        /*prints the line that tx is in, with an arrow pointing to the column
                    159:          that tx is at.
                    160:        */
                    161:        txptr lx= fcol(); intlet ap= -1, p= 0; char c; txptr ax= tx;
                    162:        if (!at) do ax--; while (Space(Char(ax)));
                    163:        while (!Eol(lx) && Char(lx) != Eotc) {
                    164:                if (lx == ax) ap= p;
                    165:                c= *lx++;
                    166:                if (c == '\t') {
                    167:                        do { putch(' '); } while (((++p)%4)!=0);
                    168:                } else { putch(c); p++; }
                    169:        }
                    170:        putch('\n');
                    171:        if (ap < 0) ap= p;
                    172:        for (p= 0; p < ap+4; p++) putch(' ');
                    173:        errmess("^\n");
                    174: }
                    175: 
                    176: Hidden bool sh_lino(lino) intlet lino; {
                    177:        switch (cntxt) {
                    178:                case In_command:
                    179:                case In_read:
                    180:                case In_edval:
                    181:                case In_tarval:
                    182:                case In_prmnv:  return No;
                    183:                case In_unit:   return lino != 1;
                    184:                default:        return Yes;
                    185:        }
                    186: }
                    187: 
                    188: 
                    189: Hidden Procedure show_line(in_node, at, node, line_no)
                    190:  bool in_node, at; parsetree node; int line_no;
                    191:  {
                    192:        if (sh_lino(line_no))
                    193:                fprintf(errfile, " in line %d of your ", line_no);
                    194:        else
                    195:                errmess(" in your ");
                    196:        switch (cntxt) {
                    197:                case In_command:        errmess("command"); break;
                    198:                case In_read:           errmess("expression to be read"); break;
                    199:                case In_edval:          errmess("edited value"); break;
                    200:                case In_tarval:         errmess("target value"); break;
                    201:                case In_unit:           errmess("unit ");
                    202:                                        release(erruname);
                    203:                                        if (Is_text(uname)) {
                    204:                                                value name; literal type;
                    205:                                                p_name_type(uname, &name, &type);
                    206:                                                prname(name); release(name);
                    207:                                                erruname= copy(uname);
                    208:                                                errlino= line_no;
                    209:                                        } else erruname= Vnil;
                    210:                                        break;
                    211:                case In_prmnv:          errmess("permanent environment"); break;
                    212:                default:                errmess("???\n"); return;
                    213:        }
                    214:        errmess("\n");
                    215:        if (!in_node || node != Vnil) errmess("    ");
                    216:        if (in_node) display(errfile, node, Yes);
                    217:        else pr_line(at);
                    218: }
                    219: 
                    220: Hidden bool unit_file() {
                    221:        value *aa;
                    222:        return cntxt == In_unit && Is_text(uname) && p_exists(uname, &aa);
                    223: }
                    224: 
                    225: Hidden Procedure show_where(in_node, at, node)
                    226:        bool in_node, at; parsetree node; {
                    227: 
                    228:        int line_no= in_node ? intval(curlino) : lino;
                    229:        if (cntxt == In_formal) { /*can only happen when in_node*/
                    230:                context cc;
                    231:                sv_context(&cc);
                    232:                set_context(&how_context);
                    233:                copy(uname);
                    234:                show_line(Yes, Yes, curline, intval(curlino));
                    235:                errmess("*** originating");
                    236:                set_context(&act_context);
                    237:                copy(uname);
                    238:                show_line(Yes, Yes, curline, intval(curlino));
                    239:                set_context(&cc);
                    240:        } else
                    241:                show_line(in_node, at, node, line_no);
                    242:        if (!Interactive && !unit_file()) {
                    243:                fprintf(errfile,
                    244:                  "*** (detected after reading %d input line%s of your input file ",
                    245:                    f_lino, f_lino == 1 ? "" : "s");
                    246:                if (iname == Vnil) errmess("standard input");
                    247:                else prname(iname);
                    248:                errmess(")\n");
                    249:        }
                    250: }
                    251: 
                    252: Hidden Procedure fatal(m, in_node) int m; bool in_node; {
                    253:        line();
                    254:        errmess("*** Sorry, B system malfunction");
                    255:        show_where(in_node, Yes, curline);
                    256:        errmess("*** The problem is: ");
                    257:        prmess(m); errmess("\n");
                    258:        errmess("*** Please save pertinent data for inspection by B guru\n");
                    259:        bye(-1);
                    260: }
                    261: 
                    262: Visible Procedure syserr(m) int m; {
                    263:        fatal(m, Yes);
                    264: }
                    265: 
                    266: #ifdef EXT_COMMAND
                    267: Visible Procedure psyserr(m) int m; {
                    268:        fatal(m, No);
                    269: }
                    270: #endif
                    271: 
                    272: Visible Procedure memexh() {
                    273:        line();
                    274:        errmess("*** Sorry, memory exhausted");
                    275: /* show_where(Yes, Yes); don't know if in node or not; to fix */ errmess("\n");
                    276:        errmess("*** Get your boss to buy a larger computer\n");
                    277:        bye(-1);
                    278: }
                    279: 
                    280: Hidden Procedure fix_files() {
                    281:        if (ifile != stdin) fclose(ifile);
                    282:        if (f_interactive(stdin) || filtered) {
                    283:                interactive= Yes;
                    284:                release(iname);
                    285:                iname = Vnil;
                    286:                ifile = stdin;
                    287:                sv_ifile= ifile;
                    288:                Eof= No;
                    289:        }
                    290: }
                    291: 
                    292: Hidden Procedure message(m1, m2, v, m3, in_node, at)
                    293:  string m1; int m2, m3; value v; bool in_node, at; {
                    294:        still_ok= No;
                    295:        line();
                    296:        errmess(m1);
                    297:        show_where(in_node, at, curline);
                    298:        errmess("*** The problem is: ");
                    299:        prmess(m2);
                    300:        if (v != Vnil) errmess(strval(v));
                    301:        prmess(m3);
                    302:        errmess("\n");
                    303:        at_nwl=Yes;
                    304: }
                    305: 
                    306: Visible Procedure pprerr(m) int m; {
                    307:        if (still_ok)
                    308:        message("*** There's something I don't understand", m, Vnil, 0, No, No);
                    309: }
                    310: 
                    311: Visible Procedure pprerr2(tag, m) value tag; int m; {
                    312:        if (still_ok)
                    313:        message("*** There's something I don't understand", 0, tag, m, No, No);
                    314: }
                    315: 
                    316: Visible Procedure parerr2(m, ss) int m, ss; {
                    317:        if (still_ok)
                    318:        message("*** There's something I don't understand", m, Vnil, ss, No, Yes);
                    319: }
                    320: 
                    321: Visible Procedure parerr(m) int m; {
                    322:        parerr2(m, 0);
                    323: }
                    324: 
                    325: Visible Procedure fixerr3(m1, v, m2) value v; int m1, m2; {
                    326:        if (still_ok)
                    327:        message("*** There's something I can't resolve", m1, v, m2, Yes, Yes);
                    328: }
                    329: 
                    330: Visible Procedure fixerr2(v, m) value v; int m; {
                    331:        fixerr3(0, v, m);
                    332: }
                    333: 
                    334: Visible Procedure fixerr(m) int m; {
                    335:        fixerr3(0, Vnil, m);
                    336: }
                    337: 
                    338: Visible Procedure error3(m1, v, m2) value v; int m1, m2; {
                    339:        message("*** Can't cope with problem", m1, v, m2, Yes, No);
                    340: }
                    341: 
                    342: Visible Procedure error2(m, v) int m; value v; {
                    343:        error3(m, v, 0);
                    344: }
                    345: 
                    346: Visible Procedure error(m) int m; {
                    347:        error3(m, Vnil, 0);
                    348: }
                    349: 
                    350: Visible Procedure checkerr() {
                    351:        still_ok= No;
                    352:        line();
                    353:        errmess("*** Your check failed");
                    354:        show_where(Yes, No, curline);
                    355:        at_nwl= Yes;
                    356: }
                    357: 
                    358: #ifdef SIGNAL
                    359: 
                    360: Visible Procedure int_signal() {
                    361:        interrupted= Yes; still_ok= No;
                    362:        if (cntxt == In_prmnv) exit(-1);
                    363:        if (!interactive) fix_files();
                    364:        if (!interactive) bye(1);
                    365:        line(); fflush(stdout);
                    366:        errmess("*** interrupted\n");
                    367: #ifndef INTEGRATION
                    368:        if (filtered) errmess("\177");
                    369: #endif
                    370:        if (cntxt == In_read) {
                    371:                set_context(&read_context);
                    372:                copy(uname);
                    373:        }
                    374:        at_nwl= Yes;
                    375: }
                    376: 
                    377: #endif SIGNAL
                    378: 
                    379: Visible bool bugs= No, testing= No, tracing= No;
                    380: 
                    381: #ifdef NOT_USED
                    382: Visible Procedure debug(m) string m; {
                    383:        if (bugs) {
                    384:                line();
                    385:                errmess("*** Debugging ");
                    386:                show_where(Yes, Yes, curline);
                    387:                fprintf(errfile, "*** %s\n", m);
                    388:                at_nwl= Yes;
                    389:        }
                    390: }
                    391: #endif
                    392: 
                    393: #ifdef EXT_COMMAND
                    394: 
                    395: /* User-callable error message */
                    396: Visible Procedure e_error(mesg) value mesg; {
                    397:        value v= convert(mesg, Yes, Yes);
                    398:        message("*** Halted", 0, v, 0, Yes, No);
                    399:        release(v);
                    400: }
                    401: 
                    402: #endif
                    403: 
                    404: Visible Procedure bye(ex) int ex; {
                    405: #ifdef EXT_COMMAND
                    406:        e_done();
                    407: #endif
                    408:        at_nwl= Yes;
                    409:        putprmnv();
                    410:        endall();
                    411:        if (ex == 0) {
                    412:                term_mem();
                    413:                endmem();
                    414:        }
                    415: #ifdef IBMPC
                    416:        memstat("at end");
                    417: #endif IBMPC
                    418:        exit(ex);
                    419: }
                    420: 
                    421: Visible Procedure initerr() {
                    422:        still_ok= Yes; interrupted= No; curline= Vnil; curlino= zero;
                    423: }
                    424: 
                    425: 
                    426: #define HZ 60 /* 4.2BSD: not line frequency but historical constant */
                    427: 
                    428: showtime(whence)
                    429:        string whence;
                    430: {
                    431: #ifdef TIMING
                    432:        static long total[2];
                    433:        long buf[4];
                    434:        extern bool timing; /* Set in b3mai.c by -T option */
                    435: 
                    436:        if (!timing) return;
                    437:        times(buf);
                    438:        line();
                    439:        fprintf(errfile, "*** Times %s: user %.2f sys %.2f (total %.2f %.2f)\n",
                    440:                whence,
                    441:                (float)(buf[0]-total[0])/HZ, (float)(buf[1]-total[1])/HZ,
                    442:                (float)total[0]/HZ, (float)total[1]/HZ
                    443:        );
                    444:        total[0]= buf[0]; total[1]= buf[1];
                    445: #endif TIMING
                    446: }

unix.superglobalmegacorp.com

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