Annotation of researchv10dc/cmd/icon/src/iconx/imain.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Initialization and error routines.
                      3:  */
                      4: 
                      5: #include "../h/rt.h"
                      6: #include "../h/version.h"
                      7: #include "gc.h"
                      8: #include "../h/header.h"
                      9: #include <signal.h>
                     10: #include <ctype.h>
                     11: #ifndef VMS
                     12: #ifndef MSDOS
                     13: #include <sys/types.h>
                     14: #include <sys/times.h>
                     15: #else MSDOS
                     16: #ifdef LATTICE
                     17: #include <fcntl.h>
                     18: #include <time.h>
                     19: #endif LATTICE
                     20: #ifdef MSoft
                     21: #include <sys/types.h>
                     22: #include <fcntl.h>
                     23: #include SysTime
                     24: #endif MSoft
                     25: #endif MSDOS
                     26: #else VMS
                     27: #include <types.h>
                     28: struct tms {
                     29:    time_t    tms_utime;                /* user time */
                     30:    time_t    tms_stime;                /* system time */
                     31:    time_t    tms_cutime;               /* user time, children */
                     32:    time_t    tms_cstime;               /* system time, children */
                     33:    };
                     34: #endif VMS
                     35: 
                     36: /*
                     37:  * A number of important variables follow.
                     38:  */
                     39: 
                     40: #ifndef MaxHeader
                     41: #define MaxHeader MaxHdr
                     42: #endif MaxHeader
                     43: 
                     44: extern putpos();                       /* assignment function for &pos */
                     45: extern putran();                       /* assignment function for &random */
                     46: extern putsub();                       /* assignment function for &subject */
                     47: extern puttrc();                       /* assignment function for &trace */
                     48: 
                     49: word *stack;                           /* interpreter stack */
                     50: int line = 0;                          /* source program line number */
                     51: int k_level = 0;                       /* &level */
                     52: struct descrip k_main;                 /* &main */
                     53: char *code;                            /* interpreter code buffer */
                     54: word *records;                         /* pointer to record procedure blocks */
                     55: word *ftab;                            /* pointer to record/field table */
                     56: struct descrip *globals, *eglobals;    /* pointer to global variables */
                     57: struct descrip *gnames, *egnames;      /* pointer to global variable names */
                     58: struct descrip *statics, *estatics;    /* pointer to static variables */
                     59: char *ident;                           /* pointer to identifier table */
                     60: 
                     61: int numbufs = NumBuf;                  /* number of i/o buffers */
                     62: char (*bufs)[BUFSIZ];                  /* pointer to buffers */
                     63: FILE **bufused;                                /* pointer to buffer use markers */
                     64: 
                     65: word tallybin[16];                     /* counters for tallying */
                     66: int tallyopt = 0;                      /* want tally results output? */
                     67: 
                     68: int mstksize = MStackSize;             /* initial size of main stack */
                     69: int stksize = StackSize;               /* co-expression stack size */
                     70: struct b_coexpr *stklist;              /* base of co-expression block list */
                     71: 
                     72: word statsize = MaxStatSize;           /* size of static region */
                     73: word statincr = MaxStatSize/4;         /* increment for static region */
                     74: char *statbase;                                /* start of static space */
                     75: char *statend;                         /* end of static space */
                     76: char *statfree;                                /* static space free pointer */
                     77: 
                     78: word ssize = MaxStrSpace;              /* initial string space size (bytes) */
                     79: char *strbase;                         /* start of string space */
                     80: char *strend;                          /* end of string space */
                     81: char *strfree;                         /* string space free pointer */
                     82: char *currend;                         /* current end of memory region */
                     83: 
                     84: word abrsize = MaxAbrSize;             /* initial size of allocated block
                     85:                                           region (bytes) */
                     86: char *blkbase;                         /* start of block region */
                     87: char *maxblk;                          /* end of allocated blocks */
                     88: char *blkfree;                         /* block region free pointer */
                     89: 
                     90: uword statneed;                                /* stated need for static space */
                     91: uword strneed;                         /* stated need for string space */
                     92: uword blkneed;                         /* stated need for block space */
                     93: 
                     94: struct descrip **quallist;             /* string qualifier list */
                     95: struct descrip **qualfree;             /* qualifier list free pointer */
                     96: struct descrip **equallist;            /* end of qualifier list */
                     97: 
                     98: int dodump;                            /* if non-zero, core dump on error */
                     99: int noerrbuf;                          /* if non-zero, do not buffer stderr */
                    100: 
                    101: struct descrip current;                        /* current expression stack pointer */
                    102: struct descrip maps2;                  /* second cached argument of map */
                    103: struct descrip maps3;                  /* third cached argument of map */
                    104: 
                    105: int ntended = 0;                       /* number of active tended descrips */
                    106: long starttime;                                /* start time of job in milliseconds */
                    107: 
                    108: /*
                    109:  * Next there are several structures for built-in values.  Parts of some
                    110:  * of these structures are initialized later.
                    111:  */
                    112: 
                    113: /*
                    114:  * Built-in csets
                    115:  */
                    116: 
                    117: /*
                    118:  * &ascii; 128 bits on, second 128 bits off.
                    119:  */
                    120: struct b_cset  k_ascii = {
                    121:    T_Cset,
                    122:    128,
                    123:    cset_display(~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
                    124:                  0,  0,  0,  0,  0,  0,  0,  0)
                    125:    };
                    126: 
                    127: /*
                    128:  * &cset; all 256 bits on.
                    129:  */
                    130: struct b_cset  k_cset = {
                    131:    T_Cset,
                    132:    256,
                    133:    cset_display(~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
                    134:                 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0)
                    135:    };
                    136: 
                    137: 
                    138: 
                    139: /*
                    140:  * Cset for &lcase; bits corresponding to lowercase letters are on.
                    141:  */
                    142: struct b_cset  k_lcase = {
                    143:    T_Cset,
                    144:    26,
                    145:    cset_display( 0,  0,  0,  0,  0,  0, ~01, 03777,
                    146:                  0,  0,  0,  0,  0,  0,  0,  0)
                    147:    };
                    148: 
                    149: /*
                    150:  * &ucase; bits corresponding to uppercase characters are on.
                    151:  */
                    152: struct b_cset  k_ucase = {
                    153:    T_Cset,
                    154:    26,
                    155:     cset_display(0,  0,  0,  0, ~01, 03777, 0, 0,
                    156:                  0,  0,  0,  0,  0,  0,  0,  0)
                    157:    };
                    158: 
                    159: /*
                    160:  * Built-in files.
                    161:  */
                    162: 
                    163: struct b_file  k_errout;               /* &errout */
                    164: struct b_file  k_input;                        /* &input */
                    165: struct b_file  k_output;               /* &outout */
                    166: 
                    167: /*
                    168:  * Keyword trapped variables.
                    169:  */
                    170: 
                    171: /*
                    172:  * &pos.
                    173:  */
                    174: struct b_tvkywd tvky_pos = {
                    175:    T_Tvkywd,
                    176:    /* putpos, */
                    177:    /* D_Integer, */
                    178:    /* 1, */
                    179:    /* 4, */
                    180:    /* "&pos" */
                    181:    };
                    182: 
                    183: /*
                    184:  * &random.
                    185:  */
                    186: struct b_tvkywd tvky_ran = {
                    187:    T_Tvkywd,
                    188:    /* putran, */
                    189:    /* D_Integer, */
                    190:    /* 0, */
                    191:    /* 7, */
                    192:    /* "&random" */
                    193:    };
                    194: 
                    195: /*
                    196:  * &subject.
                    197:  */
                    198: struct b_tvkywd tvky_sub = {
                    199:    T_Tvkywd,
                    200:    /* putsub, */
                    201:    /* 0, */
                    202:    /* 0, */
                    203:    /* 8, */
                    204:    /* "&subject" */
                    205:    };
                    206: 
                    207: /*
                    208:  * &trace.
                    209:  */
                    210: struct b_tvkywd tvky_trc = {
                    211:    T_Tvkywd,
                    212:    /* puttrc, */
                    213:    /* D_Integer, */
                    214:    /* 0, */
                    215:    /* 6, */
                    216:    /* "&trace" */
                    217:    };
                    218: 
                    219: /*
                    220:  * Co-expression block header for &main.
                    221:  */
                    222: 
                    223: static struct b_coexpr *mainhead;
                    224: 
                    225: #if IntSize == 16
                    226: /*
                    227:  * Long integer block for &random.
                    228:  */
                    229: struct b_int long_ran = {
                    230:    T_Longint,
                    231:    0L
                    232:    };
                    233: #endif IntSize == 16
                    234: 
                    235: /*
                    236:  * Various constant descriptors.
                    237:  */
                    238: 
                    239: struct descrip blank = {1, /*" "*/};
                    240: struct descrip emptystr = {0, /*""*/};
                    241: struct descrip errout = {D_File, /*&k_errout*/};
                    242: struct descrip input = {D_File, /*&k_input*/};
                    243: struct descrip lcase = {26, /*lowercase*/};
                    244: struct descrip letr = {1, /*"r"*/};
                    245: struct descrip nulldesc = {D_Null, /*0*/};
                    246: struct descrip onedesc = {D_Integer, /*1*/};
                    247: struct descrip ucase = {26, /*uppercase*/};
                    248: struct descrip zerodesc = {D_Integer, /*0*/};
                    249: 
                    250: #ifdef RunStats
                    251: #endif RunStats
                    252: 
                    253: /*
                    254:  * init - initialize memory and prepare for Icon execution.
                    255:  */
                    256: 
                    257: init(name)
                    258: char *name;
                    259:    {
                    260:    register int i;
                    261:    word cbread;
                    262:    int f;
                    263:    char c, *p;
                    264:    struct descrip *dp;
                    265:    struct header hdr;
                    266: #ifndef MSDOS
                    267:    struct tms tp;
                    268:    extern char *brk(), *sbrk(), *index();
                    269: #else MSDOS
                    270: #ifdef LPTR
                    271:    long longread();
                    272: #endif LPTR
                    273: #endif MSDOS
                    274:    extern fpetrap(), segvtrap();
                    275: 
                    276:    /*
                    277:     * Catch floating point traps and memory faults.
                    278:     */
                    279: #ifndef MSoft
                    280:    signal(SIGFPE, fpetrap);
                    281: #endif MSoft
                    282: #ifndef MSDOS
                    283: #ifdef PYRAMID
                    284: {
                    285:    struct sigvec a;
                    286: 
                    287:    a.sv_handler = fpetrap;
                    288:    a.sv_mask = 0;
                    289:    a.sv_onstack = 0;
                    290:    sigvec(SIGFPE, &a, 0);
                    291:    sigsetmask(1 << SIGFPE);
                    292: }
                    293: #else PYRAMID
                    294:    signal(SIGFPE, fpetrap);
                    295: #endif PYRAMID
                    296: #endif MSDOS
                    297: 
                    298:    /*
                    299:     * Initializations that cannot be performed statically (at least for
                    300:     * some compilers).
                    301:     */
                    302: 
                    303:    k_errout.title = T_File;
                    304:    k_errout.fd = stderr;
                    305:    k_errout.status = Fs_Write;
                    306:    k_errout.fname.dword = 7;
                    307:    StrLoc(k_errout.fname) = "&errout";
                    308: 
                    309:    k_input.title = T_File;
                    310:    k_input.fd = stdin;
                    311:    k_input.status = Fs_Read;
                    312:    k_input.fname.dword = 6;
                    313:    StrLoc(k_input.fname) = "&input";
                    314: 
                    315:    k_output.title = T_File;
                    316:    k_output.fd = stdout;
                    317:    k_output.status = Fs_Write;
                    318:    k_output.fname.dword = 7;
                    319:    StrLoc(k_output.fname) = "&output";
                    320: 
                    321:    tvky_pos.putval = putpos;
                    322:    ((tvky_pos.kyval).dword) = D_Integer;
                    323:    IntVal(tvky_pos.kyval) = 1;
                    324:    StrLen(tvky_pos.kyname) = 4;
                    325:    StrLoc(tvky_pos.kyname) = "&pos";
                    326: 
                    327:    tvky_ran.putval = putran;
                    328: #if IntSize == 16
                    329:    ((tvky_ran.kyval).dword) = D_Longint;
                    330: #else IntSize == 16
                    331:    ((tvky_ran.kyval).dword) = D_Integer;
                    332: #endif IntSize == 16
                    333:    StrLen(tvky_ran.kyname) = 7;
                    334:    StrLoc(tvky_ran.kyname) = "&random";
                    335: 
                    336:    tvky_sub.putval = putsub;
                    337:    StrLen(tvky_sub.kyval) = 0;
                    338:    StrLen(tvky_sub.kyname) = 8;
                    339:    StrLoc(tvky_sub.kyname) = "&subject";
                    340: 
                    341:    tvky_trc.putval = puttrc;
                    342:    ((tvky_trc.kyval).dword) = D_Integer;
                    343:    StrLen(tvky_trc.kyname) = 6;
                    344:    StrLoc(tvky_trc.kyname) = "&trace";
                    345: #if IntSize == 16
                    346:    BlkLoc(tvky_ran.kyval) = (union block *) &long_ran;
                    347: #else IntSize == 16
                    348:    IntVal(tvky_ran.kyval) = 0;
                    349: #endif IntSize == 16
                    350:    IntVal(tvky_trc.kyval) = 0;
                    351:    StrLoc(tvky_sub.kyval) = "";
                    352: 
                    353: 
                    354:    StrLoc(k_subject) = "";
                    355:    IntVal(nulldesc) = 0;
                    356:    maps2 = nulldesc;
                    357:    maps3 = nulldesc;
                    358:    IntVal(zerodesc) = 0;
                    359:    IntVal(onedesc) = 1;
                    360:    StrLoc(emptystr) = "";
                    361:    StrLoc(blank) = " ";
                    362:    StrLoc(letr) = "r";
                    363:    BlkLoc(input) = (union block *) &k_input;
                    364:    BlkLoc(errout) = (union block *) &k_errout;
                    365:    StrLoc(lcase) = "abcdefghijklmnopqrstuvwxyz";
                    366:    StrLoc(ucase) = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
                    367:    
                    368:    /*
                    369:     * Open the icode file and read the header.
                    370:     */
                    371:    i = strlen(name);
                    372: #ifndef MSDOS
                    373:    f = open(name, 0);
                    374: #else MSDOS
                    375: #ifdef LATTICE
                    376:    f = open(name,O_RDONLY | O_RAW);
                    377: #endif LATTICE
                    378: #ifdef MSoft
                    379:    f = open(name,O_RDONLY | O_BINARY);
                    380: #endif MSoft
                    381: #endif MSDOS
                    382:    if (f < 0)
                    383:       error("can't open interpreter file");
                    384: #ifndef NoHeader
                    385:    lseek(f, (long)MaxHeader, 0);
                    386: #endif NoHeader
                    387:    if (read(f, (char *)&hdr, sizeof(hdr)) != sizeof(hdr))
                    388:       error("can't read interpreter file header");
                    389:     
                    390:    /*
                    391:     * Establish pointers to data regions.
                    392:     */
                    393:    code = (char *)sbrk((word)0);
                    394:    k_trace = hdr.trace;
                    395:    records = (word *) (word)(code + hdr.records);
                    396:    ftab = (word *) (word)(code + hdr.ftab);
                    397:    globals = (struct descrip *) (code + hdr.globals);
                    398:    gnames = eglobals = (struct descrip *) (code + hdr.gnames);
                    399:    statics = egnames = (struct descrip *) (code + hdr.statics);
                    400:    estatics = (struct descrip *) (code + hdr.ident);
                    401:    ident = (char *) estatics;
                    402: 
                    403:    /*
                    404:     * Examine the environment and make appropriate settings.
                    405:     */
                    406:    envlook();
                    407: 
                    408:    /*
                    409:     * Convert stack sizes from words to bytes.
                    410:     */
                    411:    stksize *= WordSize;
                    412:    mstksize *= WordSize;
                    413:  
                    414:    /*
                    415:     * Set up allocated memory.  The regions are:
                    416:     *
                    417:     *  Static memory region
                    418:     *  Allocated string region
                    419:     *  Allocate block region
                    420:     *  String qualifier list
                    421:     */
                    422:    /*
                    423:     * Align bufs on a word boundary
                    424:     */
                    425:    bufs = (char **)((word)(code + hdr.hsize + 3) & ~03);
                    426:    bufused = (FILE **) (bufs + numbufs);
                    427:    statfree = statbase = (char *)(((word)(bufused + numbufs) + 63)  & ~077);
                    428:    statend = statbase + mstksize + statsize;
                    429:    strfree = strbase = (char *)((word)(statend + 63) & ~077);
                    430:    blkfree = blkbase = strend = (char *)((word)(strbase + ssize + 63) & ~077);
                    431:    quallist = qualfree = equallist =
                    432:     (struct descrip **)(maxblk = (char *)((word)(blkbase + abrsize + 63) & ~077));
                    433: 
                    434:    /*
                    435:     * Try to move the break back to the end of memory to allocate (the
                    436:     *  end of the string qualifier list) and die if the space isn't
                    437:     *  available.
                    438:     */
                    439:    if ((int)brk(equallist) == -1)
                    440:       error("insufficient memory");
                    441:    currend = sbrk(0);                  /* keep track of end of memory */
                    442: 
                    443:    /*
                    444:     * Allocate stack and initialize &main.
                    445:     */
                    446:    stack = (word *)malloc(mstksize);
                    447:    mainhead = (struct b_coexpr *)stack;
                    448:    mainhead->title = T_Coexpr;
                    449:    mainhead->activator.dword = D_Coexpr;
                    450:    BlkLoc(mainhead->activator) = (union block *)mainhead;
                    451:    mainhead->size = 0;
                    452:    mainhead->freshblk = nulldesc;      /* &main has no refresh block. */
                    453:                                        /*  This really is a bug. */
                    454: 
                    455:    /*
                    456:     * Point &main at the stack for the main procedure and set current,
                    457:     *  the pointer to the current co-expression to &main.
                    458:     */
                    459:    k_main.dword = D_Coexpr;
                    460:    BlkLoc(k_main) = (union block *) mainhead;
                    461:    current = k_main;
                    462:    
                    463:    /*
                    464:     * Read the interpretable code and data into memory.
                    465:     */
                    466: #ifndef MSDOS
                    467:    if ((cbread = read(f, code, hdr.hsize)) != hdr.hsize) {
                    468: #else MSDOS
                    469: #ifdef SPTR
                    470:    if ((cbread = read(f, code, hdr.hsize)) != hdr.hsize) {
                    471: #else /* Handle the case where hdr.hsize is long */
                    472:    if ((cbread = longread(f, code, hdr.hsize)) != hdr.hsize) {
                    473: #endif SPTR
                    474: #endif MSDOS
                    475:       fprintf(stderr,"Tried to read %ld bytes of code, and got %ld\n",
                    476:        (long)hdr.hsize,(long)cbread);
                    477:       error("can't read interpreter code");
                    478:       }
                    479:    close(f);
                    480: 
                    481: /*
                    482:  * Make sure the version number of the icode matches the interpreter version.
                    483:  */
                    484: 
                    485:    if (strcmp((char *)hdr.config,IVersion)) {
                    486:       fprintf(stderr,"icode version mismatch\n");
                    487:       fprintf(stderr,"\ticode version: %s\n",(char *)hdr.config);
                    488:       fprintf(stderr,"\texpected version: %s\n",IVersion);
                    489:       fflush(stderr);
                    490:       if (dodump)
                    491:          abort();
                    492:       c_exit(ErrorExit);
                    493:       }
                    494: 
                    495:    /*
                    496:     * Resolve references from icode to runtime system.
                    497:     */
                    498:    resolve();
                    499: 
                    500:    /*
                    501:     * Mark all buffers as available.
                    502:     */
                    503:    c = (char) NULL;
                    504:    for (i = 0; i < numbufs; i++)
                    505:       bufused[i] = (FILE *) c;
                    506: 
                    507:    /*
                    508:     * Buffer stdin if a buffer is available.
                    509:     */
                    510: #ifndef VMS
                    511:    if (numbufs >= 1) {
                    512:       setbuf(stdin, bufs[0]);
                    513:       bufused[0] = stdin;
                    514:       }
                    515:    else
                    516:       setbuf(stdin, NULL);
                    517: 
                    518:    /*
                    519:     * Buffer stdout if a buffer is available.
                    520:     */
                    521:    if (numbufs >= 2) {
                    522:       setbuf(stdout, bufs[1]);
                    523:       bufused[1] = stdout;
                    524:       }
                    525:    else
                    526:       setbuf(stdout, NULL);
                    527:    
                    528:    /*
                    529:     * Buffer stderr if a buffer is available.
                    530:     */
                    531:    if (numbufs >= 3 && !noerrbuf) {
                    532:       setbuf(stderr, bufs[2]);
                    533:       bufused[2] = stderr;
                    534:       }
                    535:    else
                    536:       setbuf(stderr, NULL);
                    537: #endif VMS
                    538: 
                    539:    /*
                    540:     * Initialize memory monitoring if enabled.
                    541:     */
                    542:    MMInit();
                    543: 
                    544:    /*
                    545:     * Get startup time.
                    546:     */
                    547: #ifndef MSDOS
                    548:    times(&tp);
                    549:    starttime = tp.tms_utime;
                    550: #else MSDOS
                    551:    time(&starttime);
                    552: #endif MSDOS
                    553:    }
                    554: 
                    555: /*
                    556:  * Check for environment variables that Icon uses and set system
                    557:  *  values as is appropriate.
                    558:  */
                    559: envlook()
                    560:    {
                    561:    register char *p;
                    562:    extern char *getenv();
                    563: 
                    564:    if ((p = getenv("TRACE")) != NULL && *p != '\0')
                    565:       k_trace = atoi(p);
                    566:    if ((p = getenv("NBUFS")) != NULL && *p != '\0')
                    567:       numbufs = atoi(p);
                    568:    if ((p = getenv("COEXPSIZE")) != NULL && *p != '\0')
                    569:       stksize = atoi(p);
                    570:    if ((p = getenv("STRSIZE")) != NULL && *p != '\0')
                    571:       ssize = atoi(p);
                    572:    if ((p = getenv("HEAPSIZE")) != NULL && *p != '\0')
                    573:       abrsize = atoi(p);
                    574:    if ((p = getenv("STATSIZE")) != NULL && *p != '\0')
                    575:       statsize = atoi(p);
                    576:    if ((p = getenv("STATINCR")) != NULL && *p != '\0')
                    577:       statincr = atoi(p);
                    578:    if ((p = getenv("MSTKSIZE")) != NULL && *p != '\0')
                    579:       mstksize = atoi(p);
                    580:    if ((p = getenv("ICONCORE")) != NULL && *p != '\0') {
                    581: #ifndef MSoft
                    582:       signal(SIGFPE, SIG_DFL);
                    583: #endif MSoft
                    584: #ifndef MSDOS
                    585:       signal(SIGSEGV, SIG_DFL);
                    586: #endif MSDOS
                    587:       dodump++;
                    588:       }
                    589:    if ((p = getenv("NOERRBUF")) != NULL)
                    590:       noerrbuf++;
                    591:    }
                    592: 
                    593: /*
                    594:  * Produce run-time error 204 on floating point traps.
                    595:  */
                    596: #ifdef PYRAMID
                    597: fpetrap(code, subcode, sp)
                    598: int code, subcode, sp;
                    599:    {
                    600:    runerr(subcode == FPE_wordOVF_EXC ? 203 : 204, NULL);
                    601:    }
                    602: #else PYRAMID
                    603: fpetrap()
                    604:    {
                    605:    runerr(204, NULL);
                    606:    }
                    607: #endif PYRAMID
                    608: 
                    609: /*
                    610:  * Produce run-time error 302 on segmentation faults.
                    611:  */
                    612: segvtrap()
                    613:    {
                    614:    runerr(302, NULL);
                    615:    }
                    616: 
                    617: /*
                    618:  * error - print error message s; used only in startup code.
                    619:  */
                    620: error(s)
                    621: char *s;
                    622:    {
                    623:    fprintf(stderr, "error in startup code\n%s\n", s);
                    624:    fflush(stderr);
                    625:    if (dodump)
                    626:       abort();
                    627:    c_exit(ErrorExit);
                    628:    }
                    629: 
                    630: /*
                    631:  * syserr - print s as a system error.
                    632:  */
                    633: syserr(s)
                    634: char *s;
                    635:    {
                    636:    struct b_proc *bp;
                    637: 
                    638:    bp = (struct b_proc *)BlkLoc(argp[0]);
                    639:    if (line > 0)
                    640:       fprintf(stderr, "System error at line %ld in %s\n%s\n", (long)line,
                    641:          bp->filename, s);
                    642:    else
                    643:       fprintf(stderr, "System error in startup code\n%s\n", s);
                    644:    fflush(stderr);
                    645:    if (dodump)
                    646:       abort();
                    647:    c_exit(ErrorExit);
                    648:    }
                    649: 
                    650: /*
                    651:  * errtab maps run-time error numbers into messages.
                    652:  */
                    653: struct errtab {
                    654:    int errno;
                    655:    char *errmsg;
                    656:    } errtab[] = {
                    657:    101, "integer expected",
                    658:    102, "numeric expected",
                    659:    103, "string expected",
                    660:    104, "cset expected",
                    661:    105, "file expected",
                    662:    106, "procedure or integer expected",
                    663:    107, "record expected",
                    664:    108, "list expected",
                    665:    109, "string or file expected",
                    666:    110, "string or list expected",
                    667:    111, "variable expected",
                    668:    112, "invalid type to size operation",
                    669:    113, "invalid type to random operation",
                    670:    114, "invalid type to subscript operation",
                    671:    115, "list or table expected",
                    672:    116, "invalid type to element generator",
                    673:    117, "missing main procedure",
                    674:    118, "co-expression expected",
                    675:    119, "set expected",
                    676: 
                    677:    201, "division by zero",
                    678:    202, "remaindering by zero",
                    679:    203, "integer overflow",
                    680:    204, "real overflow, underflow, or division by zero",
                    681:    205, "value out of range",
                    682:    206, "negative first operand to real exponentiation",
                    683:    207, "invalid field name",
                    684:    208, "second and third arguments to map of unequal length",
                    685:    209, "invalid second argument to open",
                    686:    210, "argument to system function too long",
                    687:    211, "by clause equal to zero",
                    688:    212, "attempt to read file not open for reading",
                    689:    213, "attempt to write file not open for writing",
                    690:    214, "recursive co-expression activation",
                    691: 
                    692:    301, "interpreter stack overflow",
                    693:    302, "C stack overflow",
                    694:    303, "unable to expand memory region",
                    695:    304, "memory region size changed",
                    696: 
                    697:    0,   0
                    698:    };
                    699: 
                    700: /*
                    701:  * runerr - print message corresponding to error n and if v is nonnull,
                    702:  *  print it as the offending value.
                    703:  */
                    704: #ifdef PCIX
                    705: /*
                    706:  * For PC/IX, runerr is an assembly language routine that jumps into this
                    707:  * xruner procedure past the call to csv which occurs at the beginning of
                    708:  * all C procedures. This is necessary to defeat the stack data collision
                    709:  * testing which is done in csv in pc/ix and which would cause a loop,
                    710:  * since one of the possible reasons for calling runerr in the first place
                    711:  * might be stack/data collision.
                    712:  */
                    713: xruner(n, v)
                    714: #else PCIX
                    715: runerr(n, v)
                    716: #endif PCIX
                    717: register int n;
                    718: struct descrip *v;
                    719:    {
                    720:    register struct errtab *p;
                    721:    struct b_proc *bp;
                    722: 
                    723:    if (line > 0) {
                    724:       bp = (struct b_proc *)BlkLoc(argp[0]);
                    725:       fprintf(stderr, "Run-time error %d at line %ld in %s\n", n,
                    726:          (long)line, bp->filename);
                    727:       }
                    728:    else
                    729:       fprintf(stderr, "Run-time error %d in startup code\n", n);
                    730:    for (p = errtab; p->errno > 0; p++)
                    731:       if (p->errno == n) {
                    732:          fprintf(stderr, "%s\n", p->errmsg);
                    733:          break;
                    734:          }
                    735:    if (v != NULL) {
                    736:       fprintf(stderr, "offending value: ");
                    737:       outimage(stderr, v, 0);
                    738:       putc('\n', stderr);
                    739:       }
                    740:    fflush(stderr);
                    741:    if (dodump)
                    742:       abort();
                    743:    c_exit(ErrorExit);
                    744:    }
                    745: 
                    746: /*
                    747:  * resolve - perform various fixups on the data read from the interpretable
                    748:  *  file.
                    749:  */
                    750: resolve()
                    751:    {
                    752:    register word i;
                    753:    register struct b_proc *pp;
                    754:    register struct descrip *dp;
                    755:    extern mkrec();
                    756:    extern struct b_proc *functab[];
                    757: 
                    758:    /*
                    759:     * Scan the global variable list for procedures and fill in appropriate
                    760:     *  addresses.
                    761:     */
                    762:    for (dp = globals; dp < eglobals; dp++) {
                    763:       if ((*dp).dword != D_Proc)
                    764:          continue;
                    765:       /*
                    766:        * The second word of the descriptor for procedure variables tells
                    767:        *  where the procedure is.  Negative values are used for built-in
                    768:        *  procedures and positive values are used for Icon procedures.
                    769:        */
                    770:       i = IntVal(*dp);
                    771:       if (i < 0) {
                    772:          /*
                    773:           * *dp names a built-in function, negate i and use it as an index
                    774:           *  into functab to get the location of the procedure block.
                    775:           */
                    776:          BlkLoc(*dp) = (union block *) functab[-i-1];
                    777:          }
                    778:       else {
                    779:          /*
                    780:           * *dp names an Icon procedure or a record.  i is an offset to
                    781:           *  location of the procedure block in the code section.  Point
                    782:           *  pp at the block and replace BlkLoc(*dp).
                    783:           */
                    784:          pp = (struct b_proc *) (code + i);
                    785:          BlkLoc(*dp) = (union block *) pp;
                    786:          /*
                    787:           * Relocate the address of the name of the procedure.
                    788:           */
                    789:          StrLoc(pp->pname) += (word)ident;
                    790:          if (pp->ndynam == -2)
                    791:             /*
                    792:              * This procedure is a record constructor.  Make its entry point
                    793:              *  be the entry point of mkrec().
                    794:              */
                    795:             pp->entryp.ccode = mkrec;
                    796:          else {
                    797:             /*
                    798:              * This is an Icon procedure.  Relocate the entry point and
                    799:              *  the names of the parameters, locals, and static variables.
                    800:              */
                    801:             pp->entryp.icode = code + (word)pp->entryp.icode;
                    802:             if (pp->ndynam >= 0)
                    803:                pp->filename += (word)ident;
                    804:             for (i = 0; i < pp->nparam+pp->ndynam+pp->nstatic; i++)
                    805:                StrLoc(pp->lnames[i]) += (word)ident;
                    806:             }
                    807:          }
                    808:       }
                    809:    /*
                    810:     * Relocate the names of the global variables.
                    811:     */
                    812:    for (dp = gnames; dp < egnames; dp++)
                    813:       StrLoc(*dp) += (word)ident;
                    814:    }
                    815: 
                    816: 
                    817: /*
                    818:  * c_exit(i) - flush all buffers and exit with status i.
                    819:  */
                    820: c_exit(i)
                    821: int i;
                    822: {
                    823:        int j;
                    824: 
                    825: #ifdef MemMon
                    826:        MMTerm();
                    827: #endif MemMon
                    828:        if (tallyopt) {
                    829:                fprintf(stderr,"tallies: ");
                    830:                for (j=0; j<16; j++)
                    831:                        fprintf(stderr," %ld", (long)tallybin[j]);
                    832:                fprintf(stderr,"\n");
                    833:        }
                    834:        exit(i);
                    835: }
                    836: 
                    837: err()
                    838: {
                    839:    syserr("call to 'err'\n");
                    840: }
                    841: 
                    842: #ifdef MSDOS
                    843: #ifdef LPTR
                    844: /* Write a long string in 32k chunks */
                    845: long longread(file,s,len)
                    846: int file;
                    847: char *s;
                    848: long int len;
                    849: {
                    850:    long int loopnum;
                    851:    long int leftover;
                    852:    long int tally;
                    853:    unsigned i;
                    854:    char *p;
                    855: 
                    856:    tally = 0;
                    857:    leftover = len % 32768;
                    858:    for(p = s, loopnum = len/32768;loopnum;loopnum--) {
                    859:        i = read(file,p,32768);
                    860:        tally += i;
                    861:        if (i != 32768) return tally;
                    862:        p += 32768;
                    863:    }
                    864:    if(leftover) tally += read(file,p,leftover);
                    865:    return tally;
                    866: }
                    867: #endif LPTR
                    868: #endif MSDOS

unix.superglobalmegacorp.com

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