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

1.1       root        1: /*
                      2:  * File: fmisc.c
                      3:  *  Contents: collect, copy, display, image, seq, runstats, type
                      4:  */
                      5: 
                      6: #include "../h/rt.h"
                      7: #include "gc.h"
                      8: #ifdef RunStats
                      9: #ifndef VMS
                     10: #include <sys/types.h>
                     11: #include <sys/times.h>
                     12: #else VMS
                     13: #include <types.h>
                     14: struct tms {
                     15:     time_t    tms_utime;       /* user time */
                     16:     time_t    tms_stime;       /* system time */
                     17:     time_t    tms_cutime;      /* user time, children */
                     18:     time_t    tms_cstime;      /* system time, children */
                     19: };
                     20: #endif VMS
                     21: #endif RunStats
                     22: 
                     23: #define Stralc(a,b) alcstr(a,(word)(b))
                     24: /*
                     25:  * collect() - explicit call to garbage collector.
                     26:  */
                     27: 
                     28: FncDcl(collect,0)
                     29:    {
                     30:    collect();
                     31:    Arg0 = nulldesc;
                     32:    Return;
                     33:    }
                     34: 
                     35: 
                     36: /*
                     37:  * copy(x) - make a copy of object x.
                     38:  */
                     39: 
                     40: FncDcl(copy,1)
                     41:    {
                     42:    register int i;
                     43:    struct descrip  *d1, *d2;
                     44:    union block *bp, *ep, **tp;
                     45:    extern struct b_table *alctable();
                     46:    extern struct b_telem *alctelem();
                     47:    extern struct b_set *alcset();
                     48:    extern struct b_selem *alcselem();
                     49:    extern struct b_record *alcrecd();
                     50: 
                     51:    if (Qual(Arg1))
                     52:       /*
                     53:        * x is a string, just copy its descriptor
                     54:        *  into Arg0.
                     55:        */
                     56:       Arg0 = Arg1;
                     57:    else {
                     58:       switch (Type(Arg1)) {
                     59:          case T_Null:
                     60:          case T_Integer:
                     61:          case T_Longint:
                     62:          case T_Real:
                     63:          case T_File:
                     64:          case T_Cset:
                     65:          case T_Proc:
                     66:          case T_Coexpr:
                     67:             /*
                     68:              * Copy the null value, integers, long integers, reals, files,
                     69:              *  csets, procedures, and co-expressions by copying the descriptor.
                     70:              *   Note that for integers, this results in the assignment
                     71:              *   of a value, for the other types, a pointer is directed to
                     72:              *   a data block.
                     73:              */
                     74:             Arg0 = Arg1;
                     75:             break;
                     76: 
                     77:          case T_List:
                     78:             /*
                     79:              * Pass the buck to cplist to copy a list.
                     80:              */
                     81:             cplist(&Arg1, &Arg0, (word)1, BlkLoc(Arg1)->list.size + 1);
                     82:             break;
                     83: 
                     84:          case T_Table:
                     85:             /*
                     86:              * Allocate space for table and elements and copy old table
                     87:              *  block into new.
                     88:              */
                     89:             blkreq((sizeof(struct b_table)) +
                     90:                   (sizeof(struct b_telem)) * BlkLoc(Arg1)->table.size);
                     91:             bp = (union block *) alctable(&nulldesc);
                     92:             bp->table = BlkLoc(Arg1)->table;
                     93:             /*
                     94:              * Work down the chain of table element blocks in each bucket
                     95:              *  and create identical chains in new table.
                     96:              */
                     97:             for (i = 0; i < TSlots; i++) {
                     98:                tp = &(BlkLoc(bp->table.buckets[i]));
                     99:                for (ep = *tp; ep != NULL; ep = *tp) {
                    100:                   *tp = (union block *) alctelem();
                    101:                   (*tp)->telem = ep->telem;
                    102:                   tp = &(BlkLoc((*tp)->telem.clink));
                    103:                   }
                    104:                }
                    105:             /*
                    106:              * Return the copied table.
                    107:              */
                    108:             Arg0.dword = D_Table;
                    109:             BlkLoc(Arg0) = bp;
                    110:             break;
                    111: 
                    112:          case T_Set:
                    113:             /*
                    114:              * Allocate space for set and elements and copy old set
                    115:              *  block into new.
                    116:              */
                    117:             blkreq((sizeof(struct b_set)) +
                    118:                   (sizeof(struct b_selem)) * BlkLoc(Arg1)->set.size);
                    119:             bp = (union block *) alcset(&nulldesc);
                    120:             bp->set = BlkLoc(Arg1)->set;
                    121:             /*
                    122:              * Work down the chain of set elements in each bucket
                    123:              *  and create identical chains in new set.
                    124:              */
                    125:             for (i = 0; i < SSlots; i++) {
                    126:                tp = &(BlkLoc(bp->set.sbucks[i]));
                    127:                for (ep = *tp; ep != NULL; ep = *tp) {
                    128:                   *tp = (union block *) alcselem(&nulldesc,(word)0);
                    129:                   (*tp)->selem = ep->selem;
                    130:                   tp = &(BlkLoc((*tp)->selem.clink));
                    131:                   }
                    132:                }
                    133:             /*
                    134:              * Return the copied set.
                    135:              */
                    136:             Arg0.dword = D_Set;
                    137:             BlkLoc(Arg0) = bp;
                    138:             break;
                    139: 
                    140:          case T_Record:
                    141:             /*
                    142:              * Allocate space for the new record and copy the old
                    143:              *  one into it.
                    144:              */
                    145:             blkreq(BlkLoc(Arg1)->record.blksize);
                    146:             i = BlkLoc(BlkLoc(Arg1)->record.recdesc)->proc.nfields;
                    147:             bp = (union block *)alcrecd(i,&BlkLoc(Arg1)->record.recdesc);
                    148:             bp->record = BlkLoc(Arg1)->record;
                    149:             d1 = bp->record.fields;
                    150:             d2 = BlkLoc(Arg1)->record.fields;
                    151:             while (i--)
                    152:                *d1++ = *d2++;
                    153:             /*
                    154:              * Return the copied record
                    155:              */
                    156:             Arg0.dword = D_Record;
                    157:             BlkLoc(Arg0) = bp;
                    158:             break;
                    159: 
                    160:          default:
                    161:             syserr("copy: illegal datatype.");
                    162:          }
                    163:       }
                    164:    Return;
                    165:    }
                    166: 
                    167: 
                    168: /*
                    169:  * display(i,f) - display local variables of i most recent
                    170:  * procedure activations, plus global variables.
                    171:  * Output to file f (default &errout).
                    172:  */
                    173: 
                    174: FncDcl(display,2)
                    175:    {
                    176:    struct pf_marker *fp;
                    177:    register struct descrip *dp;
                    178:    register struct descrip *np;
                    179:    register int n;
                    180:    long l;
                    181:    int count;
                    182:    FILE *f;
                    183:    struct b_proc *bp;
                    184:    extern struct descrip *globals, *eglobals;
                    185:    extern struct descrip *gnames;
                    186:    extern struct descrip *statics;
                    187: 
                    188:    /*
                    189:     * i defaults to &level; f defaults to &errout.
                    190:     */
                    191:    defint(&Arg1, &l, (word)k_level);
                    192:    deffile(&Arg2, &errout);
                    193:    /*
                    194:     * Produce error if file can't be written on.
                    195:     */
                    196:    f = BlkLoc(Arg2)->file.fd;
                    197:    if ((BlkLoc(Arg2)->file.status & Fs_Write) == 0)
                    198:       runerr(213, &Arg2);
                    199: 
                    200:    /*
                    201:     * Produce error if i is negative; constrain i to be >= &level.
                    202:     */
                    203:    if (l < 0)
                    204:       runerr(205, &Arg1);
                    205:    else if (l > k_level)
                    206:       count = k_level;
                    207:    else
                    208:       count = l;
                    209: 
                    210:    fp = pfp;           /* start fp at most recent procedure frame */
                    211:    dp = argp;
                    212:    while (count--) {           /* go back through 'count' frames */
                    213: 
                    214:       bp = (struct b_proc *) BlkLoc(*dp); /* get address of procedure block */
                    215: 
                    216:       /*
                    217:        * Print procedure name.
                    218:        */
                    219:       putstr(f, StrLoc(bp->pname), StrLen(bp->pname));
                    220:       fprintf(f, " local identifiers:\n");
                    221: 
                    222:       /*
                    223:        * Print arguments.
                    224:        */
                    225:       np = bp->lnames;
                    226:       for (n = bp->nparam; n > 0; n--) {
                    227:          fprintf(f, "   ");
                    228:          putstr(f, StrLoc(*np), StrLen(*np));
                    229:          fprintf(f, " = ");
                    230:          outimage(f, ++dp, 0);
                    231:          putc('\n', f);
                    232:          np++;
                    233:          }
                    234: 
                    235:       /*
                    236:        * Print local dynamics.
                    237:        */
                    238:       dp = &fp->pf_locals[0];
                    239:       for (n = bp->ndynam; n > 0; n--) {
                    240:          fprintf(f, "   ");
                    241:          putstr(f, StrLoc(*np), StrLen(*np));
                    242:          fprintf(f, " = ");
                    243:          outimage(f, dp++, 0);
                    244:          putc('\n', f);
                    245:          np++;
                    246:          }
                    247: 
                    248:       /*
                    249:        * Print local statics.
                    250:        */
                    251:       dp = &statics[bp->fstatic];
                    252:       for (n = bp->nstatic; n > 0; n--) {
                    253:          fprintf(f, "   ");
                    254:          putstr(f, StrLoc(*np), StrLen(*np));
                    255:          fprintf(f, " = ");
                    256:          outimage(f, dp++, 0);
                    257:          putc('\n', f);
                    258:          np++;
                    259:          }
                    260: 
                    261:       dp = fp->pf_argp;
                    262:       fp = fp->pf_pfp;
                    263:       }
                    264: 
                    265:    /*
                    266:     * Print globals.
                    267:     */
                    268:    fprintf(f, "global identifiers:\n");
                    269:    dp = globals;
                    270:    np = gnames;
                    271:    while (dp < eglobals) {
                    272:       fprintf(f, "   ");
                    273:       putstr(f, StrLoc(*np), StrLen(*np));
                    274:       fprintf(f, " = ");
                    275:       outimage(f, dp++, 0);
                    276:       putc('\n', f);
                    277:       np++;
                    278:       }
                    279:    fflush(f);
                    280:    Arg0 = nulldesc;            /* Return null value. */
                    281:    Return;
                    282:    }
                    283: 
                    284: 
                    285: /*
                    286:  * image(x) - return string image of object x.  Nothing fancy here,
                    287:  *  just plug and chug on a case-wise basis.
                    288:  */
                    289: 
                    290: FncDcl(image,1)
                    291:    {
                    292:    register word len, outlen, rnlen;
                    293:    register char *s;
                    294:    register union block *bp;
                    295:    char *type;
                    296:    extern char *alcstr();
                    297:    word prescan();
                    298:    char sbuf[MaxCvtLen];
                    299:    FILE *fd;
                    300: 
                    301:    if (Qual(Arg1)) {
                    302:       /*
                    303:        * Get some string space.  The magic 2 is for the double quote at each
                    304:        *  end of the resulting string.
                    305:        */
                    306:       strreq(prescan(&Arg1) + 2);
                    307:       len = StrLen(Arg1);
                    308:       s = StrLoc(Arg1);
                    309:       outlen = 2;
                    310: 
                    311:       /*
                    312:        * Form the image by putting a " in the string space, calling
                    313:        *  doimage with each character in the string, and then putting
                    314:        *  a " at then end.  Note that doimage directly writes into the
                    315:        *  string space.  (Hence the indentation.)  This techinique is used
                    316:        *  several times in this routine.
                    317:        */
                    318:       StrLoc(Arg0) = Stralc("\"", 1);
                    319:       while (len-- > 0)
                    320:          outlen += doimage(*s++, '"');
                    321:       Stralc("\"", 1);
                    322:       StrLen(Arg0) = outlen;
                    323:       Return;
                    324:       }
                    325: 
                    326:    switch (Type(Arg1)) {
                    327: 
                    328:       case T_Null:
                    329:          StrLoc(Arg0) = "&null";
                    330:          StrLen(Arg0) = 5;
                    331:          Return;
                    332: 
                    333:       case T_Integer:
                    334:       case T_Longint:
                    335:       case T_Real:
                    336:          /*
                    337:           * Form a string representing the number and allocate it.
                    338:           */
                    339:          cvstr(&Arg1, sbuf);
                    340:          len = StrLen(Arg1);
                    341:          strreq(len);
                    342:          StrLoc(Arg0) = alcstr(StrLoc(Arg1), len);
                    343:          StrLen(Arg0) = len;
                    344:          Return;
                    345: 
                    346:       case T_Cset:
                    347: 
                    348:          /*
                    349:           * Check for distinguished csets by looking at the address of
                    350:           *  of the object to image.  If one is found, make a string
                    351:           *  naming it and return.
                    352:           */
                    353:          if (BlkLoc(Arg1) == ((union block *) &k_ascii)) {
                    354:             StrLoc(Arg0) = "&ascii";
                    355:             StrLen(Arg0) = 6;
                    356:             Return;
                    357:             }
                    358:          else if (BlkLoc(Arg1) == ((union block *) &k_cset)) {
                    359:             StrLoc(Arg0) = "&cset";
                    360:             StrLen(Arg0) = 5;
                    361:             Return;
                    362:             }
                    363:          else if (BlkLoc(Arg1) == ((union block *) &k_lcase)) {
                    364:             StrLoc(Arg0) = "&lcase";
                    365:             StrLen(Arg0) = 6;
                    366:             Return;
                    367:             }
                    368:          else if (BlkLoc(Arg1) == ((union block *) &k_ucase)) {
                    369:             StrLoc(Arg0) = "&ucase";
                    370:             StrLen(Arg0) = 6;
                    371:             Return;
                    372:             }
                    373:          /*
                    374:           * Convert the cset to a string and proceed as is done for
                    375:           *  string images but use a ' rather than " to bound the
                    376:           *  result string.
                    377:           */
                    378:          cvstr(&Arg1, sbuf);
                    379:          strreq(prescan(&Arg1) + 2);
                    380:          len = StrLen(Arg1);
                    381:          s = StrLoc(Arg1);
                    382:          outlen = 2;
                    383:          StrLoc(Arg0) = Stralc("'", 1);
                    384:                         while (len-- > 0)
                    385:                             outlen += doimage(*s++, '\'');
                    386:                         Stralc("'", 1);
                    387:          StrLen(Arg0) = outlen;
                    388:          Return;
                    389: 
                    390:       case T_File:
                    391:          /*
                    392:           * Check for distinguished files by looking at the address of
                    393:           *  of the object to image.  If one is found, make a string
                    394:           *  naming it and return.
                    395:           */
                    396:          if ((fd = BlkLoc(Arg1)->file.fd) == stdin) {
                    397:             StrLen(Arg0) = 6;
                    398:             StrLoc(Arg0) = "&input";
                    399:             }
                    400:          else if (fd == stdout) {
                    401:             StrLen(Arg0) = 7;
                    402:             StrLoc(Arg0) = "&output";
                    403:             }
                    404:          else if (fd == stderr) {
                    405:             StrLen(Arg0) = 7;
                    406:             StrLoc(Arg0) = "&errout";
                    407:             }
                    408:          else {
                    409:             /*
                    410:              * The file is not a standard one, form a string of the form
                    411:              *  file(nm) where nm is the argument originally given to
                    412:              *  open.
                    413:              */
                    414:             strreq(prescan(&BlkLoc(Arg1)->file.fname)+6);
                    415:             len = StrLen(BlkLoc(Arg1)->file.fname);
                    416:             s = StrLoc(BlkLoc(Arg1)->file.fname);
                    417:             outlen = 6;
                    418:             StrLoc(Arg0) = Stralc("file(", 5);
                    419:                            while (len-- > 0)
                    420:                               outlen += doimage(*s++, '\0');
                    421:                            Stralc(")", 1);
                    422:             StrLen(Arg0) = outlen;
                    423:             }
                    424:          Return;
                    425: 
                    426:       case T_Proc:
                    427:          /*
                    428:           * Produce one of:
                    429:           *  "procedure name"
                    430:           *  "function name"
                    431:           *  "record constructor name"
                    432:           *
                    433:           * Note that the number of dynamic locals is used to determine
                    434:           *  what type of "procedure" is at hand.
                    435:           */
                    436:          len = StrLen(BlkLoc(Arg1)->proc.pname);
                    437:          s = StrLoc(BlkLoc(Arg1)->proc.pname);
                    438:          switch (BlkLoc(Arg1)->proc.ndynam) {
                    439:             default:  type = "procedure "; break;
                    440:             case -1:  type = "function "; break;
                    441:             case -2:  type = "record constructor "; break;
                    442:             }
                    443:          outlen = strlen(type);
                    444:          strreq(len + outlen);
                    445:          StrLoc(Arg0) = alcstr(type, outlen);
                    446:          alcstr(s, len);
                    447:          StrLen(Arg0) = len + outlen;
                    448:          Return;
                    449: 
                    450:       case T_List:
                    451:          /*
                    452:           * Produce:
                    453:           *  "list(n)"
                    454:           * where n is the current size of the list.
                    455:           */
                    456:          bp = BlkLoc(Arg1);
                    457:          sprintf(sbuf, "list(%ld)", (long)bp->list.size);
                    458:          len = strlen(sbuf);
                    459:          strreq(len);
                    460:          StrLoc(Arg0) = alcstr(sbuf, len);
                    461:          StrLen(Arg0) = len;
                    462:          Return;
                    463: 
                    464:       case T_Lelem:
                    465:          StrLen(Arg0) = 18;
                    466:          StrLoc(Arg0) = "list element block";
                    467:          Return;
                    468: 
                    469:       case T_Table:
                    470:          /*
                    471:           * Produce:
                    472:           *  "table(n)"
                    473:           * where n is the size of the table.
                    474:           */
                    475:          bp = BlkLoc(Arg1);
                    476:          sprintf(sbuf, "table(%ld)", (long)bp->table.size);
                    477:          len = strlen(sbuf);
                    478:          strreq(len);
                    479:          StrLoc(Arg0) = alcstr(sbuf, len);
                    480:          StrLen(Arg0) = len;
                    481:          Return;
                    482: 
                    483:       case T_Telem:
                    484:          StrLen(Arg0) = 19;
                    485:          StrLoc(Arg0) = "table element block";
                    486:          Return;
                    487: 
                    488:       case T_Set:
                    489:          /*
                    490:           * Produce "set(n)" where n is size of the set.
                    491:           */
                    492:          bp = BlkLoc(Arg1);
                    493:          sprintf(sbuf, "set(%ld)", (long)bp->set.size);
                    494:          len = strlen(sbuf);
                    495:          strreq(len);
                    496:          StrLoc(Arg0) = alcstr(sbuf,len);
                    497:          StrLen(Arg0) = len;
                    498:          Return;
                    499: 
                    500:       case T_Selem:
                    501:          StrLen(Arg0) = 17;
                    502:          StrLoc(Arg0) = "set element block";
                    503:          Return;
                    504: 
                    505:       case T_Record:
                    506:          /*
                    507:           * Produce:
                    508:           *  "record name(n)"
                    509:           * where n is the number of fields.
                    510:           */
                    511:          bp = BlkLoc(Arg1);
                    512:          rnlen = StrLen(BlkLoc(bp->record.recdesc)->proc.recname);
                    513:          strreq(15 + rnlen);   /* 15 = *"record " + *"(nnnnnn)" */
                    514:          bp = BlkLoc(Arg1);
                    515:          sprintf(sbuf, "(%ld)", (long)BlkLoc(bp->record.recdesc)->proc.nfields);
                    516:          len = strlen(sbuf);
                    517:          StrLoc(Arg0) = Stralc("record ", 7);
                    518:             alcstr(StrLoc(BlkLoc(bp->record.recdesc)->proc.recname),rnlen);
                    519:             alcstr(sbuf, len);
                    520:          StrLen(Arg0) = 7 + len + rnlen;
                    521:          Return;
                    522: 
                    523:       case T_Coexpr:
                    524:          /*
                    525:           * Produce:
                    526:           *  "co-expression(n)"
                    527:           * where n is the number of results that have been produced.
                    528:           */
                    529:          strreq(22);
                    530:          sprintf(sbuf, "(%ld)", (long)BlkLoc(Arg1)->coexpr.size);
                    531:          len = strlen(sbuf);
                    532:          StrLoc(Arg0) = Stralc("co-expression", 13);
                    533:          alcstr(sbuf, len);
                    534:          StrLen(Arg0) = 13 + len;
                    535:          Return;
                    536: 
                    537:       default:
                    538:          syserr("image: unknown type.");
                    539:       }
                    540:    Return;
                    541:    }
                    542: 
                    543: /*
                    544:  * doimage(c,q) - allocate character c in string space, with escape
                    545:  *  conventions if c is unprintable, '\', or equal to q.
                    546:  *  Returns number of characters allocated.
                    547:  */
                    548: 
                    549: doimage(c, q)
                    550: int c, q;
                    551:    {
                    552:    static char *cbuf = "\\\0\0\0";
                    553:    extern char *alcstr();
                    554: 
                    555:    if (c >= ' ' && c < '\177') {
                    556:       /*
                    557:        * c is printable, but special case ", ', and \.
                    558:        */
                    559:       switch (c) {
                    560:          case '"':
                    561:             if (c != q) goto def;
                    562:             Stralc("\\\"", 2);
                    563:             return 2;
                    564:          case '\'':
                    565:             if (c != q) goto def;
                    566:             Stralc("\\'", 2);
                    567:             return 2;
                    568:          case '\\':
                    569:             Stralc("\\\\", 2);
                    570:             return 2;
                    571:          default:
                    572:          def:
                    573:             cbuf[0] = c;
                    574:             cbuf[1] = '\0';
                    575:             Stralc(cbuf,1);
                    576:             return 1;
                    577:          }
                    578:       }
                    579: 
                    580:    /*
                    581:     * c is some sort of unprintable character.  If it is one of the common
                    582:     *  ones, produce a special representation for it, otherwise, produce
                    583:     *  its octal value.
                    584:     */
                    585:    switch (c) {
                    586:       case '\b':                       /*      backspace    */
                    587:          Stralc("\\b", 2);
                    588:          return 2;
                    589:       case '\177':                     /*      delete       */
                    590:          Stralc("\\d", 2);
                    591:          return 2;
                    592:       case '\33':                      /*      escape       */
                    593:          Stralc("\\e", 2);
                    594:          return 2;
                    595:       case '\f':                       /*      form feed    */
                    596:          Stralc("\\f", 2);
                    597:          return 2;
                    598:       case '\n':                       /*      new line     */
                    599:          Stralc("\\n", 2);
                    600:          return 2;
                    601:       case '\r':                       /*      return       */
                    602:          Stralc("\\r", 2);
                    603:          return 2;
                    604:       case '\t':                       /*      horizontal tab     */
                    605:          Stralc("\\t", 2);
                    606:          return 2;
                    607:       case '\13':                      /*      vertical tab     */
                    608:          Stralc("\\v", 2);
                    609:          return 2;
                    610:       default:                         /*      octal constant  */
                    611:          cbuf[0] = '\\';
                    612:          cbuf[1] = ((c&0300) >> 6) + '0';
                    613:          cbuf[2] = ((c&070) >> 3) + '0';
                    614:          cbuf[3] = (c&07) + '0';
                    615:          Stralc(cbuf, 4);
                    616:          return 4;
                    617:       }
                    618:    }
                    619: 
                    620: /*
                    621:  * prescan(d) - return upper bound on length of expanded string.  Note
                    622:  *  that the only time that prescan is wrong is when the string contains
                    623:  *  one of the "special" unprintable characters, e.g. tab.
                    624:  */
                    625: word prescan(d)
                    626: struct descrip *d;
                    627:    {
                    628:    register word slen, len;
                    629:    register char *s, c;
                    630: 
                    631:    s = StrLoc(*d);
                    632:    len = 0;
                    633:    for (slen = StrLen(*d); slen > 0; slen--)
                    634:       if ((c = (*s++)) < ' ' || c >= 0177)
                    635:          len += 4;
                    636:       else if (c == '"' || c == '\\' || c == '\'')
                    637:          len += 2;
                    638:       else
                    639:          len++;
                    640: 
                    641:    return len;
                    642:    }
                    643: 
                    644: 
                    645: /*
                    646:  * seq(e1,e2)  - generate e1, e1+e2, e1+e2+e2, ... .
                    647:  */
                    648: 
                    649: FncDcl(seq,2)
                    650:    {
                    651:    long from, by;
                    652: 
                    653:    /*
                    654:     * Default e1 and e2 to 1.
                    655:     */
                    656:    defint(&Arg1, &from, (word)1);
                    657:    defint(&Arg2, &by, (word)1);
                    658:    
                    659:    /*
                    660:     * Produce error if e2 is 0, i.e., infinite sequence of e1's.
                    661:     */
                    662:    if (by == 0)
                    663:       runerr(211, &Arg2);
                    664: 
                    665:    /*
                    666:     * Suspend sequence, stopping when largest or smallest integer
                    667:     *  is reached.
                    668:     */
                    669:    while ((from <= MaxLong && by > 0) || (from >= MinLong && by < 0)) {
                    670:       Mkint(from, &Arg0);
                    671:       Suspend;
                    672:       from += by;
                    673:       }
                    674:    Fail;
                    675:    }
                    676: 
                    677: 
                    678: #ifdef RunStats
                    679: /*
                    680:  * runstats - return all sorts of junk (and junk of all sorts)
                    681:  */
                    682: FncDcl(runstats,0)
                    683:    {
                    684:    extern char *alcstr();
                    685:    char fmt[500],*p,*q;
                    686:    int i;
                    687:    struct tms tp;
                    688:    long time(), clock, runtim;
                    689:    times(&tp);
                    690: 
                    691: #ifndef MSDOS
                    692:    runtim = 1000 * ((tp.tms_utime - starttime) / (double)Hz);
                    693: #else MSDOS
                    694:    runtim = time() - starttime;
                    695: #endif MSDOS
                    696: 
                    697: #define NValues1  47
                    698:    for ((i = 1,p=fmt); i <= NValues1; i++) {
                    699:        q = "%s\t%d\n";
                    700:          while (*p++ = *q++);
                    701:          --p;
                    702:          }
                    703: 
                    704:    strreq(3000);       /* just a guess */
                    705:    sprintf(strfree,fmt,
                    706:          "Lines executed/ex",ex_n_lines,
                    707:          "Opcodes executed/ex",ex_n_opcodes,
                    708:          "Total time/ex",runtim,
                    709:          "Invocations/ex",ex_n_invoke,
                    710:          "Icon procedure invocations/ex",ex_n_ipinvoke,
                    711:          "Built-in procedure invocations/ex",ex_n_bpinvoke,
                    712:          "Argument list adjustments/ex",ex_n_argadjust,
                    713:          "Operator invocations/ex",ex_n_opinvoke,
                    714:          "goal-directed invocations/ex",ex_n_mdge,
                    715:          "String invocations/ex",ex_n_stinvoke,
                    716:          "Keyword references/ex",ex_n_keywd,
                    717:          "Local variable references/ex",ex_n_locref,
                    718:          "Global variable references/ex",ex_n_globref,
                    719:          "Static variable references/ex",ex_n_statref,
                    720:          
                    721:          "Expression suspensions/gde",gde_n_esusp,
                    722:          "Esusp bytes copied/gde",gde_bc_esusp,
                    723:          "Icon procedure suspensions/gde",gde_n_psusp,
                    724:          "Psusp bytes copied/gde",gde_bc_psusp,
                    725:          "Operator & built-in suspensions/gde",gde_n_susp,
                    726:          "Susp bytes copied/gde",gde_bc_susp,
                    727:          
                    728:          "Expression failures/gde",gde_n_efail,
                    729:          "Icon procedure failures/gde",gde_n_pfail,
                    730:          "Operator & built-in failures/gde",gde_n_fail,
                    731:          "Evaluation resumptions/gde",gde_n_resume,
                    732:          "Expression returns/gde",gde_n_eret,
                    733:          "Icon procedure returns/gde",gde_n_pret,
                    734:          
                    735:        "Block Region Size/gc",maxblk-blkbase,
                    736:          "Block Region Usage/gc",blkfree-blkbase,
                    737:          "String Size/gc",strend-strbase,
                    738:          "String Usage/gc",strfree-strbase,
                    739: 
                    740:          "Garbage collections/gc",gc_n_total,
                    741:          "String triggered collections/gc",gc_n_string,
                    742:          "Block region triggered collections/gc",gc_n_blk,
                    743:          "CE triggered collections/gc",gc_n_coexpr,
                    744:          
                    745:          "Total garbage collection time/gc",gc_t_total,
                    746:          "Last garbage collection time/gc",gc_t_last,
                    747: 
                    748:          "Dereferences/ev",ev_n_deref,
                    749:          "No-op dereferences/ev",ev_n_redunderef,
                    750:          "Tv substring dereferences/ev",ev_n_tsderef,
                    751:          "Tv table dereferences/ev",ev_n_ttderef,
                    752:          "&pos dereferences/ev",ev_n_tpderef,
                    753: 
                    754:          "Cvint operations/cv",cv_n_int,
                    755:          "No-op cvint operations/cv",cv_n_rint,
                    756:          "Cvreal operations/cv",cv_n_real,
                    757:          "No-op cvreal operations/cv",cv_n_rreal,
                    758:          "Cvnum operations/cv",cv_n_num,
                    759:          "No-op cvnum operations/cv",cv_n_rnum,
                    760:          "Cvstr operations/cv",cv_n_str,
                    761:          "No-op cvstr operations/cv",cv_n_rstr,
                    762:          "Cvcset operations/cv",cv_n_cset,
                    763:          "No-op cvcset operations/cv",cv_n_rcset,
                    764:          0,0,0,0);
                    765: 
                    766: #define NValues2  15
                    767:    for ((i = 1,p=fmt); i <= NValues2; i++) {
                    768:        q = "%s\t%d\n";
                    769:          while (*p++ = *q++);
                    770:          --p;
                    771:          }
                    772: 
                    773:    sprintf(strfree+strlen(strfree),fmt,
                    774:          "Block region allocations/al",al_n_total,
                    775:          "Total block space allocated/al",al_bc_btotal,
                    776:          "String allocations/al",al_n_str,
                    777:          "Total string space allocated/al",al_bc_stotal,
                    778:          "Trapped substring allocations/al",al_n_subs,
                    779:          "Cset allocations/al",al_n_cset,
                    780:          "Real number allocations/al",al_n_real,
                    781:          "List allocations/al",al_n_list,
                    782:          "List block allocations/al",al_n_lstb,
                    783:          "Table allocations/al",al_n_table,
                    784:          "Table element allocations/al",al_n_telem,
                    785:          "Table element tvars/al",al_n_tvtbl,
                    786:          "File block allocations/al",al_n_file,
                    787:          "Co-expression block allocations/al",al_n_eblk,
                    788:          "Co-expression stack allocations/al",al_n_estk,
                    789: 
                    790:          0,0,0,0 /* who can count? */
                    791:          );
                    792:    StrLoc(Arg0) = alcstr(strfree,(word)strlen(strfree));
                    793:    StrLen(Arg0) = alcstr(StrLoc(Arg0));
                    794:    Return;
                    795:    }
                    796: #else RunStats
                    797: char junk;     /* prevent empty object module */
                    798: #endif RunStats
                    799: 
                    800: 
                    801: /*
                    802:  * type(x) - return type of x as a string.
                    803:  */
                    804: 
                    805: /* >type1 */
                    806: FncDcl(type,1)
                    807:    {
                    808: 
                    809:    if (Qual(Arg1)) {
                    810:       StrLen(Arg0) = 6;
                    811:       StrLoc(Arg0) = "string";
                    812:       }
                    813: 
                    814:    else {
                    815:       switch (Type(Arg1)) {
                    816: 
                    817:          case T_Null:
                    818:             StrLen(Arg0) = 4;
                    819:             StrLoc(Arg0) = "null";
                    820:             break;
                    821: 
                    822:          case T_Integer:
                    823:          case T_Longint:
                    824:             StrLen(Arg0) = 7;
                    825:             StrLoc(Arg0) = "integer";
                    826:             break;
                    827: 
                    828:          case T_Real:
                    829:             StrLen(Arg0) = 4;
                    830:             StrLoc(Arg0) = "real";
                    831:             break;
                    832: /* <type1 */
                    833: 
                    834:          case T_Cset:
                    835:             StrLen(Arg0) = 4;
                    836:             StrLoc(Arg0) = "cset";
                    837:             break;
                    838: 
                    839:          case T_File:
                    840:             StrLen(Arg0) = 4;
                    841:             StrLoc(Arg0) = "file";
                    842:             break;
                    843: 
                    844:          case T_Proc:
                    845:             StrLen(Arg0) = 9;
                    846:             StrLoc(Arg0) = "procedure";
                    847:             break;
                    848: 
                    849:          case T_List:
                    850:             StrLen(Arg0) = 4;
                    851:             StrLoc(Arg0) = "list";
                    852:             break;
                    853: 
                    854:          case T_Table:
                    855:             StrLen(Arg0) = 5;
                    856:             StrLoc(Arg0) = "table";
                    857:             break;
                    858: 
                    859:          case T_Set:
                    860:             StrLen(Arg0) = 3;
                    861:             StrLoc(Arg0) = "set";
                    862:             break;
                    863: 
                    864:          case T_Record:
                    865:             Arg0 = BlkLoc(BlkLoc(Arg1)->record.recdesc)->proc.recname;
                    866:             break;
                    867: 
                    868:          case T_Coexpr:
                    869:             StrLen(Arg0) = 13;
                    870:             StrLoc(Arg0) = "co-expression";
                    871:             break;
                    872: 
                    873: 
                    874:          default:
                    875:             syserr("type: unknown type.");
                    876: /* >type2 */
                    877:          }
                    878:       }
                    879:    Return;
                    880:    }
                    881: /* <type2 */

unix.superglobalmegacorp.com

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