|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.