Annotation of 43BSD/contrib/icon/iconx/init.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Initialization and error routines.
        !             3:  */
        !             4: 
        !             5: #include "../h/rt.h"
        !             6: #include "../h/gc.h"
        !             7: #include <signal.h>
        !             8: #include <sys/types.h>
        !             9: #include <sys/times.h>
        !            10: #define MAXHDRLN       100             /* max len of #! line */
        !            11: #define MAXHDR         1024L           /* size of autoloading header--!! must
        !            12:                                            agree with that in link/ilink.c */
        !            13: char *file = "";                       /* source program file name */
        !            14: int line = 0;                          /* source program line number */
        !            15: char *code;                            /* interpreter code buffer */
        !            16: int *records;                          /* ptr to record procedure blocks */
        !            17: int *ftab;                             /* ptr to record/field table */
        !            18: struct descrip *globals, *eglobals;    /* ptr to global variables */
        !            19: struct descrip *gnames, *egnames;      /* ptr to global variable names */
        !            20: struct descrip *statics, *estatics;    /* ptr to static variables */
        !            21: char *ident;                           /* ptr to identifier table */
        !            22: int *monbuf;                           /* monitor buffer for profiling */
        !            23: int monres = 0;                                /* resolution of monitor buffer */
        !            24: int monsize = 0;                       /* size of monitor buffer */
        !            25: 
        !            26: int numbufs = NUMBUF;                  /* number of i/o buffers */
        !            27: char (*bufs)[BUFSIZ];                  /* pointer to buffers */
        !            28: FILE **bufused;                                /* pointer to buffer use markers */
        !            29: 
        !            30: int nstacks = MAXSTACKS;               /* initial number of coexpr stacks */
        !            31: int stksize = STACKSIZE;               /* coexpression stack size */
        !            32: int dodump;                            /* if non-zero, core dump on error */
        !            33: int noerrbuf;                          /* if non-zero, DON'T buffer stderr */
        !            34: int *stacks;                           /* start of stack space */
        !            35: int *estacks;                          /* end of stack space */
        !            36: int *esfree;                           /* stack space free list pointer */
        !            37: 
        !            38: int ssize = MAXSTRSPACE;               /* initial string space size (bytes) */
        !            39: char *strings;                         /* start of string space */
        !            40: char *estrings;                                /* end of string space */
        !            41: char *sfree;                           /* string space free pointer */
        !            42: 
        !            43: int hpsize = MAXHEAPSIZE;              /* initial heap size (bytes) */
        !            44: char *hpbase;                          /* start of heap */
        !            45: char *maxheap;                         /* end of heap storage */
        !            46: char *hpfree;                          /* heap free space pointer */
        !            47: unsigned heapneed;                     /* stated need for heap space */
        !            48: unsigned strneed;                      /* stated need for string space */
        !            49: 
        !            50: struct descrip **sqlist;               /* string qualifier list */
        !            51: struct descrip **sqfree;               /* s. q. list free pointer */
        !            52: struct descrip **esqlist;              /* end of s. q. list */
        !            53: 
        !            54: struct descrip current;                        /* current expression stack pointer */
        !            55: 
        !            56: /*
        !            57:  * &ascii cset, first 128 bits on, second 128 bits off.
        !            58:  */
        !            59: struct b_cset  k_ascii = {
        !            60:    T_CSET,
        !            61:    cset_display(~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
        !            62:                  0,  0,  0,  0,  0,  0,  0,  0)
        !            63:    };
        !            64: 
        !            65: /*
        !            66:  * &cset cset, all 256 bits on.
        !            67:  */
        !            68: struct b_cset  k_cset = {
        !            69:    T_CSET,
        !            70:    cset_display(~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
        !            71:                 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0)
        !            72:    };
        !            73: 
        !            74: /*
        !            75:  * File block for &errout.
        !            76:  */
        !            77: struct b_file  k_errout = {
        !            78:    T_FILE,
        !            79:    stderr,
        !            80:    FS_WRITE,
        !            81:    7,
        !            82:    /*"&errout", */
        !            83:    };
        !            84: 
        !            85: /*
        !            86:  * File block for &input.
        !            87:  */
        !            88: struct b_file  k_input = {
        !            89:    T_FILE,
        !            90:    stdin,
        !            91:    FS_READ,
        !            92:    6,
        !            93:    /*"&input",*/
        !            94:    };
        !            95: 
        !            96: /*
        !            97:  * cset for &lcase, bits corresponding to lowercase letters are on.
        !            98:  */
        !            99: struct b_cset  k_lcase = {
        !           100:    T_CSET,
        !           101:    cset_display( 0,  0,  0,  0,  0,  0, ~01, 03777,
        !           102:                  0,  0,  0,  0,  0,  0,  0,  0)
        !           103:    };
        !           104: 
        !           105: int            k_level = 0;            /* &level */
        !           106: struct descrip k_main;                 /* &main */
        !           107: int            k_pos = 1;              /* &pos */
        !           108: 
        !           109: /*
        !           110:  * File block for &output.
        !           111:  */
        !           112: struct b_file  k_output = {
        !           113:    T_FILE,
        !           114:    stdout,
        !           115:    FS_WRITE,
        !           116:    7,
        !           117:    /*"&output",*/
        !           118:    };
        !           119: 
        !           120: long           k_random = 0L;          /* &random */
        !           121: struct descrip k_subject = {           /* &subject */
        !           122:    0,
        !           123:    /*1,*/
        !           124:    };
        !           125: int k_trace = 0;
        !           126: /*
        !           127:  * cset for &ucase, bits corresponding to uppercase characters are on.
        !           128:  */
        !           129: struct b_cset  k_ucase = {
        !           130:    T_CSET,
        !           131:     cset_display(0,  0,  0,  0, ~01, 03777, 0, 0,
        !           132:                  0,  0,  0,  0,  0,  0,  0,  0)
        !           133:    };
        !           134: 
        !           135: /*
        !           136:  * maps2 and maps3 are used by the map function as caches.
        !           137:  */
        !           138: struct descrip maps2 = {
        !           139:    D_NULL,
        !           140:    /*0,*/
        !           141:    };
        !           142: struct descrip maps3 = {
        !           143:    D_NULL,
        !           144:    /*0,*/
        !           145:    };
        !           146: 
        !           147: long starttime;                                /* starttime of job in milliseconds */
        !           148: 
        !           149: struct descrip nulldesc = {D_NULL, /*0*/};
        !           150: struct descrip zerodesc = {D_INTEGER, /*0*/};
        !           151: struct descrip onedesc  = {D_INTEGER, /*1*/};
        !           152: struct descrip nullstr  = {0, /*""*/};
        !           153: struct descrip blank    = {1, /*" "*/};
        !           154: struct descrip letr     = {1, /*"r"*/};
        !           155: struct descrip input    = {D_FILE, /*&k_input*/};
        !           156: struct descrip errout   = {D_FILE, /*&k_errout*/};
        !           157: struct descrip lcase    = {26, /*lowercase*/};
        !           158: struct descrip ucase    = {26, /*uppercase*/};
        !           159: 
        !           160: static struct b_estack mainhead;       /* expression stack head for main */
        !           161: 
        !           162: /*
        !           163:  * init - initialize memory and prepare for Icon execution.
        !           164:  */
        !           165: 
        !           166: #ifdef VAX
        !           167: init(name)
        !           168: #endif VAX
        !           169: #ifdef PORT
        !           170: init(name)
        !           171: #endif PORT
        !           172: #ifdef PDP11
        !           173: init(nargs, name)
        !           174: int nargs;
        !           175: #endif PDP11
        !           176: char *name;
        !           177:    {
        !           178:    register int i;
        !           179:    int cbread;
        !           180:    int f;
        !           181:    FILE *ufile;
        !           182:    char uheader[MAXHDRLN];
        !           183:    int directex;
        !           184:    /*
        !           185:     * Interpretable file header
        !           186:     */
        !           187:    struct header {
        !           188:       int size;                        /* size of icode file */
        !           189:       int trace;               /* initial value of &trace */
        !           190:       int records;             /* records */
        !           191:       int ftab;                        /* record field table */
        !           192:       int globals;             /* global array */
        !           193:       int gnames;              /* global name array */
        !           194:       int statics;             /* static array */
        !           195:       int ident;               /* strings for identifiers, etc. */
        !           196:       } hdr;
        !           197:    struct tms tp;
        !           198:    extern char *brk(), end;
        !           199:    extern char Pstart, Pstop;
        !           200:    extern fpetrap(), segvtrap();
        !           201: 
        !           202:    /*
        !           203:     * Catch floating point traps and memory faults.
        !           204:     */
        !           205:    signal(SIGFPE, fpetrap);
        !           206:    signal(SIGSEGV, segvtrap);
        !           207: 
        !           208:    /*
        !           209:     * Initializations that can't be performed statically.
        !           210:     */
        !           211:    STRLOC(k_errout.fname)      = "&errout";
        !           212:    STRLOC(k_input.fname)       = "&input";
        !           213:    STRLOC(k_output.fname)      = "&output";
        !           214:    STRLOC(k_subject)           = (char *) 1;
        !           215:    STRLOC(maps2)               = 0;
        !           216:    STRLOC(maps3)               = 0;
        !           217:    STRLOC(nulldesc)            = 0;
        !           218:    INTVAL(zerodesc)            = 0;
        !           219:    INTVAL(onedesc)             = 1;
        !           220:    STRLOC(nullstr)             = "";
        !           221:    STRLOC(blank)               = " ";
        !           222:    STRLOC(letr)                        = "r";
        !           223:    BLKLOC(input)               = (union block *) &k_input;
        !           224:    BLKLOC(errout)              = (union block *) &k_errout;
        !           225:    STRLOC(lcase)               = "abcdefghijklmnopqrstuvwxyz";
        !           226:    STRLOC(ucase)               = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        !           227:    
        !           228:    /*
        !           229:     * Initialize &main.
        !           230:     */
        !           231:    mainhead.type = T_ESTACK;
        !           232:    mainhead.activator.type = D_NULL;
        !           233:    STRLOC(mainhead.activator) = NULL;
        !           234:    mainhead.sbase = (int *)(STKBASE);
        !           235:    mainhead.sp = NULL;
        !           236:    mainhead.boundary = NULL;
        !           237:    mainhead.nresults = 0;
        !           238:    mainhead.freshblk.type = D_NULL;
        !           239:    STRLOC(mainhead.freshblk)  = 0;
        !           240: 
        !           241:    /*
        !           242:     * Open the interpretable file and read the header.
        !           243:     */
        !           244:    i = strlen(name);
        !           245:    f = open(name, 0);
        !           246:    if (f < 0)
        !           247:       error("can't open interpreter file");
        !           248:    /*
        !           249:     * We check to see if the header starts with #! and if so, we assume
        !           250:     *  that it is being directly executed and seek past the header.
        !           251:     */
        !           252:    ufile = fdopen(f,"r");
        !           253:    fgets(uheader,MAXHDRLN,ufile);
        !           254:    if (strncmp(uheader,"#!",2) != 0) {
        !           255:       fseek(ufile,MAXHDR,0);
        !           256:       fgets(uheader,MAXHDRLN,ufile);
        !           257:       if (strncmp(uheader,"#!",2) == 0)
        !           258:          lseek(f,MAXHDR+(long)strlen(uheader),0);
        !           259:       else
        !           260:         error("invalid format for interpretable file");
        !           261:         }
        !           262:    else
        !           263:       lseek(f,(long)strlen(uheader),0);
        !           264: 
        !           265:    if (read(f, &hdr, sizeof hdr) != sizeof hdr)
        !           266:       error("can't read interpreter file header");
        !           267:     
        !           268:    /*
        !           269:     * Establish pointers to data regions.
        !           270:     */
        !           271:    code = (char *) sbrk(0);
        !           272:    k_trace = hdr.trace;
        !           273:    records = (int *) (code + hdr.records);
        !           274:    ftab = (int *) (code + hdr.ftab);
        !           275:    globals = (struct descrip *) (code + hdr.globals);
        !           276:    gnames = eglobals = (struct descrip *) (code + hdr.gnames);
        !           277:    statics = egnames = (struct descrip *) (code + hdr.statics);
        !           278:    estatics = (struct descrip *) (code + hdr.ident);
        !           279:    ident = (char *) estatics;
        !           280: 
        !           281:    /*
        !           282:     * Examine the environment and make appropriate settings.
        !           283:     */
        !           284:    envlook();
        !           285:  
        !           286:    /*
        !           287:     * Set up stuff for monitoring.
        !           288:     */
        !           289:    if (monres > 0)
        !           290:       monsize = (&Pstop - &Pstart + monres - 1) / monres;
        !           291:    monbuf = (int *)((int)(code + hdr.size + 1) & ~01);
        !           292: 
        !           293:    /*
        !           294:     * Set up allocated memory.  The regions are:
        !           295:     *  Monitoring buffer
        !           296:     *  Co-expression stacks
        !           297:     *  String space
        !           298:     *  Heap
        !           299:     *  String qualifier list
        !           300:     */
        !           301:     bufs = (char **) (monbuf + monsize);
        !           302:    bufused = (FILE **) (bufs + numbufs);
        !           303:    stacks = (int *)(((int)(bufused + numbufs) + 63)  & ~077);
        !           304:    estacks = stacks + nstacks * stksize;
        !           305:    sfree = strings = (char *)((int)(estacks + 63) & ~077);
        !           306:    hpfree = hpbase = estrings = (char *)((int)(strings + ssize + 63) & ~077);
        !           307:    sqlist = sqfree = esqlist =
        !           308:     (struct descrip **)(maxheap = (char *)((int)(hpbase + hpsize + 63) & ~077));
        !           309: 
        !           310:    /*
        !           311:     * Try to move the break back to the end of memory to allocate (the
        !           312:     *  end of the string qualifier list) and die if the space isn't
        !           313:     *  available.
        !           314:     */
        !           315:    if (brk(esqlist))
        !           316:       error("insufficient memory");
        !           317:    
        !           318:    /*
        !           319:     * Read the interpretable code and data into memory.
        !           320:     */
        !           321:    if ((cbread = read(f, code, hdr.size)) != hdr.size) {
        !           322:       fprintf(stderr,"Tried to read %d bytes of code, and got %d\n",
        !           323:         hdr.size,cbread);
        !           324:       error("can't read interpreter code");
        !           325:       }
        !           326:    close(f);
        !           327: 
        !           328:    /*
        !           329:     * Resolve references from icode to runtime system.
        !           330:     */
        !           331:    resolve();
        !           332: 
        !           333:    /*
        !           334:     * Establish linked list of free co-expression stacks.  esfree
        !           335:     *  is the base.
        !           336:     */
        !           337:    esfree = NULL;
        !           338:    for (i = nstacks-1; i >= 0; i--) {
        !           339:       *(stacks + (i * stksize)) = (int) esfree;
        !           340:       esfree = stacks + (i * stksize);
        !           341:       *(esfree+(stksize-sizeof(struct b_estack)/WORDSIZE)) = T_ESTACK;
        !           342:       }
        !           343: 
        !           344:    /*
        !           345:     * Mark all buffers as available.
        !           346:     */
        !           347:    for (i = 0; i < numbufs; i++)
        !           348:       bufused[i] = NULL;
        !           349: 
        !           350:    /*
        !           351:     * Buffer stdin if a buffer is available.
        !           352:     */
        !           353:    if (numbufs >= 1) {
        !           354:       setbuf(stdin, bufs[0]);
        !           355:       bufused[0] = stdin;
        !           356:       }
        !           357:    else
        !           358:       setbuf(stdin, NULL);
        !           359: 
        !           360:    /*
        !           361:     * Buffer stdout if a buffer is available.
        !           362:     */
        !           363:    if (numbufs >= 2) {
        !           364:       setbuf(stdout, bufs[1]);
        !           365:       bufused[1] = stdout;
        !           366:       }
        !           367:    else
        !           368:       setbuf(stdout, NULL);
        !           369:    
        !           370:    /*
        !           371:     * Buffer stderr if a buffer is available.
        !           372:     */
        !           373:    if (numbufs >= 3 && !noerrbuf) {
        !           374:       setbuf(stderr, bufs[2]);
        !           375:       bufused[2] = stderr;
        !           376:       }
        !           377:    else
        !           378:       setbuf(stderr, NULL);
        !           379: 
        !           380:    /*
        !           381:     * Point &main at the stack for the main procedure and set current,
        !           382:     *  the pointer to the current co-expression to &main.
        !           383:     */
        !           384:    k_main.type = D_ESTACK;
        !           385:    BLKLOC(k_main) = (union block *) &mainhead;
        !           386:    current = k_main;
        !           387: 
        !           388: #ifdef AZ_NEVER
        !           389:    /*
        !           390:     * Turn on monitoring if so directed.
        !           391:     */
        !           392:    if (monres > 0)
        !           393:       monitor(&Pstart, &Pstop, monbuf, monsize, 0);
        !           394: #endif AZ_NEVER
        !           395: 
        !           396:    /*
        !           397:     * Get startup time.
        !           398:     */
        !           399:    times(&tp);
        !           400:    starttime = tp.tms_utime;
        !           401:    }
        !           402: 
        !           403: /*
        !           404:  * Check for environment variables that Icon uses and set system
        !           405:  *  values as is appropriate.
        !           406:  */
        !           407: envlook()
        !           408:    {
        !           409:    register char *p;
        !           410:    extern char *getenv();
        !           411: 
        !           412:    if ((p = getenv("TRACE")) != NULL && *p != '\0')
        !           413:       k_trace = atoi(p);
        !           414:    if ((p = getenv("NBUFS")) != NULL && *p != '\0')
        !           415:       numbufs = atoi(p);
        !           416:    if ((p = getenv("NSTACKS")) != NULL && *p != '\0')
        !           417:       nstacks = atoi(p);
        !           418:    if ((p = getenv("STKSIZE")) != NULL && *p != '\0')
        !           419:       stksize = atoi(p);
        !           420:    if ((p = getenv("STRSIZE")) != NULL && *p != '\0')
        !           421:       ssize = atoi(p);
        !           422:    if ((p = getenv("HEAPSIZE")) != NULL && *p != '\0')
        !           423:       hpsize = atoi(p);
        !           424: #ifdef AZ_NEVER
        !           425:    if ((p = getenv("PROFILE")) != NULL && *p != '\0')
        !           426:       monres = atoi(p);
        !           427: #endif AZ_NEVER
        !           428:    if ((p = getenv("ICONCORE")) != NULL) {
        !           429:       signal(SIGFPE, SIG_DFL);
        !           430:       signal(SIGSEGV, SIG_DFL);
        !           431:       dodump++;
        !           432:       }
        !           433:    if ((p = getenv("NOERRBUF")) != NULL)
        !           434:       noerrbuf++;
        !           435:    }
        !           436: 
        !           437: /*
        !           438:  * Produce run-time error 204 on floating point traps.
        !           439:  */
        !           440: fpetrap()
        !           441:    {
        !           442:    runerr(204, NULL);
        !           443:    }
        !           444: 
        !           445: /*
        !           446:  * Produce run-time error 304 on segmentation faults.
        !           447:  */
        !           448: segvtrap()
        !           449:    {
        !           450:    runerr(304, NULL);
        !           451:    }
        !           452: 
        !           453: /*
        !           454:  * error - print error message s, used only in startup code.
        !           455:  */
        !           456: error(s)
        !           457: char *s;
        !           458:    {
        !           459:    if (line > 0)
        !           460:       fprintf(stderr, "error at line %d in %s\n%s\n", line, file, s);
        !           461:    else
        !           462:       fprintf(stderr, "error in startup code\n%s\n", s);
        !           463:    fflush(stderr);
        !           464:    if (dodump)
        !           465:       abort();
        !           466:    c_exit(2);
        !           467:    }
        !           468: 
        !           469: /*
        !           470:  * syserr - print s as a system error.
        !           471:  */
        !           472: syserr(s)
        !           473: char *s;
        !           474:    {
        !           475:    if (line > 0)
        !           476:       fprintf(stderr, "System error at line %d in %s\n%s\n", line, file, s);
        !           477:    else
        !           478:       fprintf(stderr, "System error in startup code\n%s\n", s);
        !           479:    fflush(stderr);
        !           480:    if (dodump)
        !           481:       abort();
        !           482:    c_exit(2);
        !           483:    }
        !           484: 
        !           485: /*
        !           486:  * errtab maps run-time error numbers into messages.
        !           487:  */
        !           488: struct errtab {
        !           489:    int errno;
        !           490:    char *errmsg;
        !           491:    } errtab[] = {
        !           492: #include "../h/err.h"
        !           493:    0,   0
        !           494:    };
        !           495: 
        !           496: /*
        !           497:  * runerr - print message corresponding to error n and if v is non-null,
        !           498:  *  print it as the offending value.
        !           499:  */
        !           500: runerr(n, v)
        !           501: register int n;
        !           502: struct descrip *v;
        !           503:    {
        !           504:    register struct errtab *p;
        !           505: 
        !           506:    if (line > 0)
        !           507:       fprintf(stderr, "Run-time error %d at line %d in %s\n", n, line, file);
        !           508:    else
        !           509:       fprintf(stderr, "Run-time error %d in startup code\n", n);
        !           510:    for (p = errtab; p->errno > 0; p++)
        !           511:       if (p->errno == n) {
        !           512:          fprintf(stderr, "%s\n", p->errmsg);
        !           513:          break;
        !           514:          }
        !           515:    if (v != NULL) {
        !           516:       fprintf(stderr, "offending value: ");
        !           517:       outimage(stderr, v, 0);
        !           518:       putc('\n', stderr);
        !           519:       }
        !           520:    fflush(stderr);
        !           521:    if (dodump)
        !           522:       abort();
        !           523:    c_exit(2);
        !           524:    }
        !           525: 
        !           526: /*
        !           527:  * External declarations for blocks of built-in procedures.
        !           528:  */
        !           529: extern struct b_proc
        !           530: #define PDEF(p) B/**/p,
        !           531: #include "../h/pdef.h"
        !           532:        interp; /* Hack to avoid ,; at end */
        !           533: #undef PDEF
        !           534: 
        !           535: /*
        !           536:  * Array of addresses of blocks for built-in procedures.  It is important
        !           537:  *  that this table and the one in link/builtin.c agree; the linker
        !           538:  *  supplies iconx with indices into this array.
        !           539:  */
        !           540: struct b_proc *functab[] = {
        !           541: #define PDEF(p) &B/**/p,
        !           542: #include "../h/pdef.h"
        !           543: #undef PDEF
        !           544:    0
        !           545:    };
        !           546: 
        !           547: /*
        !           548:  * resolve - perform various fixups on the data read from the interpretable
        !           549:  *  file.
        !           550:  */
        !           551: resolve()
        !           552:    {
        !           553:    register int i;
        !           554:    register struct b_proc *pp;
        !           555:    register struct descrip *dp;
        !           556:    extern mkrec();
        !           557: 
        !           558:    /*
        !           559:     * Scan the global variable list for procedures and fill in appropriate
        !           560:     *  addresses.
        !           561:     */
        !           562:    for (dp = globals; dp < eglobals; dp++) {
        !           563:       if (TYPE(*dp) != T_PROC)
        !           564:          continue;
        !           565:       /*
        !           566:        * The second word of the descriptor for procedure variables tells
        !           567:        *  where the procedure is.  Negative values are used for built-in
        !           568:        *  procedures and positive values are used for Icon procedures.
        !           569:        */
        !           570:       i = INTVAL(*dp);
        !           571:       if (i < 0) {
        !           572:          /*
        !           573:           * *dp names a built-in function, negate i and use it as an index
        !           574:           *  into functab to get the location of the procedure block.
        !           575:           */
        !           576:          BLKLOC(*dp) = (union block *) functab[-i-1];
        !           577:          }
        !           578:       else {
        !           579:          /*
        !           580:           * *dp names an Icon procedure or a record.  i is an offset to
        !           581:           *  location of the procedure block in the code section.  Point
        !           582:           *  pp at the block and replace BLKLOC(*dp).
        !           583:           */
        !           584:          pp = (struct b_proc *) (code + i);
        !           585:          BLKLOC(*dp) = (union block *) pp;
        !           586:          /*
        !           587:           * Relocate the address of the name of the procedure.
        !           588:           */
        !           589:          STRLOC(pp->pname) += (int)ident;
        !           590:          if (pp->ndynam == -2)
        !           591:             /*
        !           592:              * This procedure is a record constructor.  Make its entry point
        !           593:              *  be the entry point of mkrec().
        !           594:              */
        !           595:             pp->entryp = EntryPoint(mkrec);
        !           596:          else {
        !           597:             /*
        !           598:              * This is an Icon procedure.  Relocate the entry point and
        !           599:              *  the names of the parameters, locals, and static variables.
        !           600:              */
        !           601:             pp->entryp = code + (int)pp->entryp;
        !           602:             for (i = 0; i < pp->nparam+pp->ndynam+pp->nstatic; i++)
        !           603:                STRLOC(pp->lnames[i]) += (int)ident;
        !           604:             }
        !           605:          }
        !           606:       }
        !           607:    /*
        !           608:     * Relocate the names of the global variables.
        !           609:     */
        !           610:    for (dp = gnames; dp < egnames; dp++)
        !           611:       STRLOC(*dp) += (int)ident;
        !           612:    }

unix.superglobalmegacorp.com

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