|
|
1.1 ! root 1: #ifndef lint ! 2: static char *rcsid = ! 3: "$Header: io.c,v 1.11 85/03/24 11:03:19 sklower Exp $"; ! 4: #endif ! 5: ! 6: /* -[Tue Nov 22 10:01:14 1983 by jkf]- ! 7: * io.c $Locker: $ ! 8: * input output functions ! 9: * ! 10: * (c) copyright 1982, Regents of the University of California ! 11: */ ! 12: ! 13: #include "global.h" ! 14: #include <ctype.h> ! 15: #include "chars.h" ! 16: #include "chkrtab.h" ! 17: ! 18: struct readtable { ! 19: unsigned char ctable[132]; ! 20: } initread = { ! 21: /* ^@ nul ^A soh ^B stx ^C etx ^D eot ^E eng ^F ack ^G bel */ ! 22: VERR, VERR, VERR, VERR, VERR, VERR, VERR, VERR, ! 23: /* ^H bs ^I ht ^J nl ^K vt ^L np ^M cr ^N so ^O si */ ! 24: VCHAR, VSEP, VSEP, VSEP, VSEP, VSEP, VERR, VERR, ! 25: /* ^P dle ^Q dc1 ^R dc2 ^S dc3 ^T dc4 ^U nak ^V syn ^W etb */ ! 26: VERR, VERR, VERR, VERR, VERR, VERR, VERR, VERR, ! 27: /* ^X can ^Y em ^Z sub ^[ esc ^\ fs ^] gs ^^ rs ^_ us */ ! 28: VERR, VERR, VERR, VSEP, VERR, VERR, VERR, VERR, ! 29: /* sp ! " # $ % & ' */ ! 30: VSEP, VCHAR, VSD, VCHAR, VCHAR, VCHAR, VCHAR, VSQ, ! 31: /* ( ) * + , - . / */ ! 32: VLPARA, VRPARA, VCHAR, VSIGN, VCHAR, VSIGN, VPERD, VCHAR, ! 33: /* 0 1 2 3 4 5 6 7 */ ! 34: VNUM, VNUM, VNUM, VNUM, VNUM, VNUM, VNUM, VNUM, ! 35: /* 8 9 : ; < = > ? */ ! 36: VNUM, VNUM, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, ! 37: /* @ A B C D E F G */ ! 38: VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, ! 39: /* H I J K L M N O */ ! 40: VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, ! 41: /* P Q R S T U V W */ ! 42: VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, ! 43: /* X Y Z [ \ ] ^ _ */ ! 44: VCHAR, VCHAR, VCHAR, VLBRCK, VESC, VRBRCK, VCHAR, VCHAR, ! 45: /* ` a b c d e f g */ ! 46: VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, ! 47: /* h i j k l m n o */ ! 48: VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, ! 49: /* p q r s t u v w */ ! 50: VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, ! 51: /* x y z { | } ~ del */ ! 52: VCHAR, VCHAR, VCHAR, VCHAR, VDQ, VCHAR, VCHAR, VERR, ! 53: /* unused Xsdc Xesc Xdqc */ ! 54: 0, '"', '\\', '|' ! 55: }; ! 56: ! 57: extern unsigned char *ctable; ! 58: lispval atomval; /* external varaible containing atom returned ! 59: from internal atom reading routine */ ! 60: lispval readrx(); lispval readr(); lispval readry(); ! 61: char *atomtoolong(); ! 62: int keywait; ! 63: int plevel = -1; /* contains maximum list recursion count */ ! 64: int plength = -1; /* maximum number of list elements printed */ ! 65: static int dbqflag; ! 66: static int mantisfl = 0; ! 67: extern int uctolc; ! 68: extern lispval lastrtab; /* external variable designating current reader ! 69: table */ ! 70: static char baddot1[]= ! 71: "Bad reader construction: (. <something>)\nShould be (nil . <something>)\n"; ! 72: static char baddot2[]= ! 73: "Bad reader construction: (<something> . <something> not followed by )"; ! 74: ! 75: /* readr ****************************************************************/ ! 76: /* returns a s-expression read in from the port specified as the first */ ! 77: /* argument. Handles superbrackets, reader macros. */ ! 78: lispval ! 79: readr(useport) ! 80: FILE *useport; ! 81: { ! 82: register lispval handy = Vreadtable->a.clb; ! 83: ! 84: chkrtab(handy); ! 85: rbktf = FALSE; ! 86: rdrport = (FILE *) useport; ! 87: if(useport==stdin) ! 88: keywait = TRUE; ! 89: handy = readrx(Iratom()); ! 90: if(useport==stdin) ! 91: keywait = FALSE; ! 92: return(handy); ! 93: ! 94: } ! 95: ! 96: ! 97: /* readrx **************************************************************/ ! 98: /* returns a s-expression beginning with the syntax code of an atom */ ! 99: /* passed in the first */ ! 100: /* argument. Does the actual work for readr, including list, dotted */ ! 101: /* pair, and quoted atom detection */ ! 102: lispval ! 103: readrx(code) ! 104: register int code; ! 105: { ! 106: register lispval work; ! 107: register lispval *current; ! 108: register struct argent *result; ! 109: int inlbkt = FALSE; ! 110: lispval errorh(); ! 111: Savestack(4); /* ???not necessary because np explicitly restored if ! 112: changed */ ! 113: ! 114: top: ! 115: switch(code) ! 116: { ! 117: case TLBKT: ! 118: inlbkt = TRUE; ! 119: case TLPARA: ! 120: result = np; ! 121: current = (lispval *)np; ! 122: np++->val = nil; /*protect(nil);*/ ! 123: for(EVER) { ! 124: switch(code = Iratom()) ! 125: { ! 126: case TRPARA: ! 127: if(rbktf && inlbkt) ! 128: rbktf = FALSE; ! 129: goto out; ! 130: default: ! 131: atomval = readrx(code); ! 132: case TSCA: ! 133: np++->val=atomval; ! 134: *current = work = newdot(); ! 135: work->d.car = atomval; ! 136: np--; ! 137: current = (lispval *) &(work->d.cdr); ! 138: break; ! 139: case TINF: ! 140: imacrox(result->val,TRUE); ! 141: work = atomval; ! 142: result->val = work->d.car; ! 143: current = (lispval *) & (result->val); ! 144: goto mcom; ! 145: case TSPL: ! 146: macrox(); /* input and output in atomval */ ! 147: *current = atomval; ! 148: mcom: ! 149: while(*current!=nil) { ! 150: if(TYPE(*current)!=DTPR) ! 151: errorh1(Vermisc,"Non-list returned from splicing macro",nil,FALSE,7,*current); ! 152: current=(lispval *)&((*current)->d.cdr); ! 153: } ! 154: break; ! 155: case TPERD: ! 156: if(result->val==nil) { ! 157: work = result->val=newdot(); ! 158: current = (lispval *) &(work->d.cdr); ! 159: fprintf(stderr,baddot1); ! 160: } ! 161: work = readrx(TLPARA); ! 162: if (work->d.cdr!=nil) { ! 163: *current = work; work = newdot(); ! 164: work->d.cdr = *current; *current = nil; ! 165: work->d.car = result->val; ! 166: result->val = errorh1(Vermisc,baddot2,nil,TRUE,58,work); ! 167: goto out; ! 168: } ! 169: *current = work->d.car; ! 170: /* there is the possibility that the expression ! 171: following the dot is terminated with a "]" ! 172: and thus needs no closing lparens to follow ! 173: */ ! 174: if(rbktf && inlbkt) ! 175: rbktf = FALSE; ! 176: goto out; ! 177: case TEOF: ! 178: errorh1(Vermisc,"Premature end of file after ", ! 179: nil,FALSE,0,result->val); ! 180: } ! 181: if(rbktf) { ! 182: if(inlbkt) ! 183: rbktf = FALSE; ! 184: goto out; ! 185: } ! 186: } ! 187: case TSCA: ! 188: Restorestack(); ! 189: return(atomval); ! 190: case TEOF: ! 191: Restorestack(); ! 192: return(eofa); ! 193: case TMAC: ! 194: macrox(); ! 195: Restorestack(); ! 196: return(atomval); ! 197: case TINF: ! 198: imacrox(nil,FALSE); ! 199: work = atomval; ! 200: if(work==nil) { code = Iratom(); goto top;} ! 201: work = work->d.car; ! 202: Restorestack(); ! 203: if(work->d.cdr==nil) ! 204: return(work->d.car); ! 205: else ! 206: return(work); ! 207: case TSPL: ! 208: macrox(); ! 209: if((work = atomval)!=nil) { ! 210: if(TYPE(work)==DTPR && work->d.cdr==nil) { ! 211: Restorestack(); ! 212: return(work->d.car); ! 213: } else { ! 214: errorh1(Vermisc, ! 215: "Improper value returned from splicing macro at top-level",nil,FALSE,9,work); ! 216: } ! 217: } ! 218: code = Iratom(); ! 219: goto top; ! 220: /* return(readrx(Iratom())); */ ! 221: case TSQ: ! 222: result = np; ! 223: protect(newdot()); ! 224: (work = result->val)->d.car = quota; ! 225: work = work->d.cdr = newdot(); ! 226: work->d.car = readrx(Iratom()); ! 227: goto out; ! 228: ! 229: case TRPARA: ! 230: Restorestack(); ! 231: return(errorh(Vermisc, ! 232: "read: read a right paren when expecting an s-expression", ! 233: nil,FALSE,0)); ! 234: case TPERD: ! 235: Restorestack(); ! 236: return(errorh(Vermisc, ! 237: "read: read a period when expecting an s-expression", ! 238: nil,FALSE,0)); ! 239: ! 240: /* should never get here, we should have covered all cases above */ ! 241: default: ! 242: Restorestack(); ! 243: return(errorh1(Vermisc,"Readlist error, code ",nil,FALSE,0,inewint((long)code))); ! 244: } ! 245: out: ! 246: work = result->val; ! 247: np = result; ! 248: Restorestack(); ! 249: return(work); ! 250: } ! 251: macrox() ! 252: { ! 253: FILE *svport; ! 254: lispval handy, Lapply(); ! 255: ! 256: Savestack(0); ! 257: svport = rdrport; /* save from possible changing */ ! 258: lbot = np; ! 259: protect(handy=Iget(atomval,lastrtab)); ! 260: if (handy == nil) ! 261: { ! 262: errorh1(Vermisc,"read: can't find the character macro for ",nil, ! 263: FALSE,0,atomval); ! 264: } ! 265: protect(nil); ! 266: atomval = Lapply(); ! 267: chkrtab(Vreadtable->a.clb); /* the macro could have changed ! 268: the readtable ! 269: */ ! 270: rdrport = svport; /* restore old value */ ! 271: Restorestack(); ! 272: return; ! 273: } ! 274: imacrox(current,inlist) ! 275: register lispval current; ! 276: { ! 277: FILE *svport; ! 278: register lispval work; ! 279: lispval Lapply(), handy; ! 280: ! 281: Savestack(2); ! 282: svport = rdrport; /* save from possible changing */ ! 283: if(inlist) ! 284: { ! 285: protect(handy = newdot()); ! 286: handy->d.car = current; ! 287: for(work = handy->d.car; (TYPE(work->d.cdr))==DTPR; ) ! 288: work = work->d.cdr; ! 289: handy->d.cdr = work; ! 290: } ! 291: else handy = current; ! 292: ! 293: lbot = np; ! 294: protect(Iget(atomval,lastrtab)); ! 295: protect(handy); ! 296: atomval = Lfuncal(); ! 297: chkrtab(Vreadtable->a.clb); /* the macro could have changed ! 298: the readtable ! 299: */ ! 300: rdrport = svport; /* restore old value */ ! 301: Restorestack(); ! 302: return; ! 303: } ! 304: ! 305: ! 306: ! 307: /* ratomr ***************************************************************/ ! 308: /* this routine returns a pointer to an atom read in from the port given*/ ! 309: /* by the first argument */ ! 310: lispval ! 311: ratomr(useport) ! 312: register FILE *useport; ! 313: { ! 314: rdrport = useport; ! 315: switch(Iratom()) ! 316: { ! 317: case TEOF: ! 318: return(eofa); ! 319: case TSQ: ! 320: case TRPARA: ! 321: case TLPARA: ! 322: case TLBKT: ! 323: case TPERD: ! 324: strbuf[1]=0; ! 325: return(getatom(TRUE)); ! 326: default: ! 327: return(atomval); ! 328: } ! 329: } ! 330: ! 331: #define push(); *name++ = c; if(name>=endstrb) name = atomtoolong(name); ! 332: #define next() (((cc=getc(useport))!=EOF)?(stats = ctable[c = cc &0177]):\ ! 333: ((c=0),(saweof = 1),(stats = SEPMASK))) ! 334: Iratom() ! 335: { ! 336: register FILE *useport = rdrport; ! 337: register char c, marker, *name; ! 338: extern lispval finatom(), calcnum(), getnum(); ! 339: int code, cc; ! 340: int strflag = FALSE; ! 341: ! 342: name = strbuf; ! 343: ! 344: again: cc = getc(useport); ! 345: if(cc==EOF) ! 346: { ! 347: clearerr(useport); ! 348: return(TEOF); ! 349: } ! 350: c = cc & 0177; ! 351: *name = c; ! 352: ! 353: switch(synclass(ctable[c])) { ! 354: ! 355: default: goto again; ! 356: ! 357: case synclass(VNUM): ! 358: ! 359: case synclass(VSIGN): *name++ = c; ! 360: atomval = (getnum(name)); ! 361: return(TSCA); ! 362: ! 363: case synclass(VESC): ! 364: dbqflag = TRUE; ! 365: *name++ = getc(useport) & 0177; ! 366: atomval = (finatom(name)); ! 367: return(TSCA); ! 368: ! 369: case synclass(VCHAR): ! 370: if(uctolc && isupper(c)) c = tolower(c); ! 371: *name++ = c; ! 372: atomval = (finatom(name)); ! 373: return(TSCA); ! 374: ! 375: case synclass(VLPARA): return(TLPARA); ! 376: ! 377: case synclass(VRPARA): return(TRPARA); ! 378: ! 379: case synclass(VPERD): marker = peekc(useport) & 0177; ! 380: if(synclass(VNUM)!=synclass(ctable[marker])) ! 381: { if(SEPMASK & ctable[marker]) ! 382: return(TPERD); ! 383: else { *name++ = c; /* this period begins an atm */ ! 384: atomval = finatom(name); ! 385: return(TSCA); ! 386: } ! 387: } ! 388: *name++ = '.'; ! 389: mantisfl = 1; ! 390: atomval = (getnum(name)); ! 391: return(TSCA); ! 392: ! 393: case synclass(VLBRCK): return(TLBKT); ! 394: ! 395: case synclass(VRBRCK): rbktf = TRUE; ! 396: return(TRPARA); ! 397: ! 398: case synclass(VSQ): return(TSQ); ! 399: ! 400: case synclass(VSD): strflag = TRUE; ! 401: case synclass(VDQ): name = strbuf; ! 402: marker = c; ! 403: while ((c = getc(useport)) != marker) { ! 404: ! 405: if(synclass(VESC)==synclass(ctable[c])) ! 406: c = getc(useport) & 0177; ! 407: push(); ! 408: if (feof(useport)) { ! 409: clearerr(useport); ! 410: error("EOF encountered while reading atom", FALSE); ! 411: } ! 412: } ! 413: *name = NULL_CHAR; ! 414: if(strflag) ! 415: atomval = (lispval) newstr(TRUE); ! 416: else ! 417: atomval = (getatom(TRUE)); ! 418: return(TSCA); ! 419: ! 420: case synclass(VERR): if (c == '\0') ! 421: { ! 422: fprintf(stderr,"[read: null read and ignored]\n"); ! 423: goto again; /* null pname */ ! 424: } ! 425: fprintf(stderr,"%c (%o): ",c,(int) c); ! 426: error("ILLEGAL CHARACTER IN ATOM",TRUE); ! 427: ! 428: case synclass(VSINF): ! 429: code = TINF; ! 430: goto same; ! 431: case synclass(VSSPL): ! 432: code = TSPL; ! 433: goto same; ! 434: case synclass(VSMAC): ! 435: code = TMAC; ! 436: same: ! 437: marker = peekc(rdrport); ! 438: if(! (SEPMASK & ctable[marker]) ) { ! 439: *name++ = c; /* this is not a macro */ ! 440: atomval = (finatom(name)); ! 441: return(TSCA); ! 442: } ! 443: goto simple; ! 444: case synclass(VINF): ! 445: code = TINF; ! 446: goto simple; ! 447: case synclass(VSCA): ! 448: code = TSCA; ! 449: goto simple; ! 450: case synclass(VSPL): ! 451: code = TSPL; ! 452: goto simple; ! 453: case synclass(VMAC): ! 454: code = TMAC; ! 455: simple: ! 456: strbuf[0] = c; ! 457: strbuf[1] = 0; ! 458: atomval = (getatom(TRUE)); ! 459: return(code); ! 460: } ! 461: } ! 462: ! 463: lispval ! 464: getnum(name) ! 465: register char *name; ! 466: { ! 467: unsigned char c; ! 468: register lispval result; ! 469: register FILE *useport=rdrport; ! 470: unsigned char stats; ! 471: int sawdigit = 0, saweof = 0,cc; ! 472: char *exploc = (char *) 0; ! 473: double realno; ! 474: extern lispval finatom(), calcnum(), newdoub(), dopow(); ! 475: ! 476: if(mantisfl) { ! 477: mantisfl = 0; ! 478: next(); ! 479: goto mantissa; ! 480: } ! 481: if(VNUM==ctable[*(unsigned char*)(name-1)]) sawdigit = 1; ! 482: while(VNUM==next()) { ! 483: push(); /* recognize [0-9]*, in "ex" parlance */ ! 484: sawdigit = 1; ! 485: } ! 486: if(c=='.') { ! 487: push(); /* continue */ ! 488: } else if(stats & SEPMASK) { ! 489: if(!saweof)ungetc((int)c,useport); ! 490: return(calcnum(strbuf,name,(int)ibase->a.clb->i)); ! 491: } else if(c=='^') { ! 492: push(); ! 493: return(dopow(name,(int)ibase->a.clb->i)); ! 494: } else if(c=='_') { ! 495: if(sawdigit) /* _ must be preceeded by a digit */ ! 496: { ! 497: push(); ! 498: return(dopow(name,2)); ! 499: } ! 500: else goto backout; ! 501: } else if(c=='e' || c=='E' || c=='d' ||c=='D') { ! 502: if(sawdigit) goto expt; ! 503: else goto backout; ! 504: } else { ! 505: backout: ! 506: ungetc((int)c,useport); ! 507: return(finatom(name)); ! 508: } ! 509: /* at this point we have [0-9]*\. , which might ! 510: be a decimal int or the leading part of a ! 511: float */ ! 512: if(next()!=VNUM) { ! 513: if(c=='e' || c=='E' || c=='d' ||c=='D') ! 514: goto expt; ! 515: else if(c=='^') { ! 516: push(); ! 517: return(dopow(name,(int)ibase->a.clb->i)); ! 518: } else if(c=='_') { ! 519: push(); ! 520: return(dopow(name,2)); ! 521: } else if( stats & SEPMASK) { ! 522: /* Here we have 1.x where x is not number ! 523: * but is a separator ! 524: * Here we have decimal int. NOT FORTRAN! ! 525: */ ! 526: if(!saweof)ungetc((int)c,useport); ! 527: return(calcnum(strbuf,name-1,10)); ! 528: } ! 529: else goto last; /* return a symbol */ ! 530: } ! 531: mantissa: ! 532: do { ! 533: push(); ! 534: } while (VNUM==next()); ! 535: ! 536: /* Here we have [0-9]*\.[0-9]* ! 537: * three possibilities: ! 538: * next character is e,E,d or D in which case we examine ! 539: * the exponent [then we are faced with a similar ! 540: * situation to this one: is the character after the ! 541: * exponent a separator or not] ! 542: * next character is a separator, in which case we have a ! 543: * number (without an exponent) ! 544: * next character is not a separator in which case we have ! 545: * an atom (whose prefix just happens to look like a ! 546: * number) ! 547: */ ! 548: if( (c == 'e') || (c == 'E') || (c == 'd') || (c == 'D')) goto expt; ! 549: ! 550: if(stats & SEPMASK) goto verylast; /* a real number */ ! 551: else goto last; /* prefix makes it look like a number, but it isn't */ ! 552: ! 553: expt: ! 554: exploc = name; /* remember location of exponent character */ ! 555: push(); ! 556: next(); ! 557: if(c=='+' || c =='-') { ! 558: push(); ! 559: next(); ! 560: } ! 561: while (VNUM==stats) { ! 562: push(); ! 563: next(); ! 564: } ! 565: ! 566: /* if a separator follows then we have a number, else just ! 567: * an atom ! 568: */ ! 569: if (stats & SEPMASK) goto verylast; ! 570: ! 571: last: /* get here when what looks like a number turns out to be an atom */ ! 572: if(!saweof) ungetc((int)c,useport); ! 573: return(finatom(name)); ! 574: ! 575: verylast: ! 576: if(!saweof) ungetc((int)c,useport); ! 577: /* scanf requires that the exponent be 'e' */ ! 578: if(exploc != (char *) 0 ) *exploc = 'e'; ! 579: *name=0; ! 580: sscanf(strbuf,"%F",&realno); ! 581: (result = newdoub())->r = realno; ! 582: return(result); ! 583: } ! 584: ! 585: lispval ! 586: dopow(part2,base) ! 587: register char *part2; ! 588: { ! 589: register char *name = part2; ! 590: register FILE *useport = rdrport; ! 591: register int power; ! 592: lispval work; ! 593: unsigned char stats,c; ! 594: int cc, saweof = 0; ! 595: char *end1 = part2 - 1; lispval Ltimes(); ! 596: Savestack(4); ! 597: ! 598: while(VNUM==next()) { ! 599: push(); ! 600: } ! 601: if(c!='.') { ! 602: if(!saweof)ungetc((int)c,useport); ! 603: } ! 604: if(c!='.' && !(stats & SEPMASK)) { ! 605: return(finatom(name)); ! 606: } ! 607: lbot = np; ! 608: np++->val = inewint(base); ! 609: /* calculate "mantissa"*/ ! 610: if(*end1=='.') ! 611: np++->val = calcnum(strbuf,end1-1,10); ! 612: else ! 613: np++->val = calcnum(strbuf,end1,(int)ibase->a.clb->i); ! 614: ! 615: /* calculate exponent */ ! 616: if(c=='.') ! 617: power = calcnum(part2,name,10)->i; ! 618: else ! 619: power = calcnum(part2,name,(int)ibase->a.clb->i)->i; ! 620: while(power-- > 0) ! 621: lbot[1].val = Ltimes(); ! 622: work = lbot[1].val; ! 623: Restorestack(); ! 624: return(work); ! 625: } ! 626: ! 627: ! 628: lispval ! 629: calcnum(strbuf,name,base) ! 630: register char *name; ! 631: char *strbuf; ! 632: { ! 633: register char *p; ! 634: register lispval result, temp; ! 635: int negflag = 0; ! 636: ! 637: result = temp = newsdot(); /* initialize sdot cell */ ! 638: protect(temp); ! 639: p = strbuf; ! 640: if(*p=='+') p++; ! 641: else if(*p=='-') {negflag = 1; p++;} ! 642: *name = 0; ! 643: if(p>=name) return(getatom(TRUE)); ! 644: ! 645: for(;p < name; p++) ! 646: dmlad(temp,(long)base,(long)*p-'0'); ! 647: if(negflag) ! 648: dmlad(temp,-1L,0L); ! 649: ! 650: if(temp->s.CDR==0) { ! 651: result = inewint(temp->i); ! 652: pruneb(np[-1].val); ! 653: } ! 654: np--; ! 655: return(result); ! 656: } ! 657: lispval ! 658: finatom(name) ! 659: register char *name; ! 660: { ! 661: register FILE *useport = rdrport; ! 662: unsigned char c, stats; ! 663: int cc, saweof = 0; ! 664: ! 665: while(!(next()&SEPMASK)) { ! 666: ! 667: if(synclass(stats) == synclass(VESC)) { ! 668: c = getc(useport) & 0177; ! 669: } else { ! 670: if(uctolc && isupper(c)) c = tolower(c); ! 671: } ! 672: push(); ! 673: } ! 674: *name = NULL_CHAR; ! 675: if(!saweof)ungetc((int)c,useport); ! 676: return(getatom(TRUE)); ! 677: } ! 678: ! 679: char * ! 680: atomtoolong(copyto) ! 681: char *copyto; ! 682: { ! 683: int size; ! 684: register char *oldp = strbuf; ! 685: register char *newp; ! 686: lispval nveci(); ! 687: /* ! 688: * the string buffer contains an string which is too long ! 689: * so we get a bigger buffer. ! 690: */ ! 691: ! 692: size = (endstrb - strbuf)*4 + 28 ; ! 693: newp = (char *) nveci(size); ! 694: atom_buffer = (lispval) newp; ! 695: strbuf = newp; ! 696: endstrb = newp + size - 1; ! 697: while(oldp < copyto) *newp++ = *oldp++; ! 698: return(newp); ! 699: } ! 700: ! 701: /* printr ***************************************************************/ ! 702: /* prints the first argument onto the port specified by the second */ ! 703: ! 704: /* ! 705: * Last modified Mar 21, 1980 for hunks ! 706: */ ! 707: ! 708: printr(a,useport) ! 709: register lispval a; ! 710: register FILE *useport; ! 711: { ! 712: register hsize, i; ! 713: char strflag = 0; ! 714: char Idqc = 0; ! 715: char *chstr; ! 716: int curplength = plength; ! 717: int quot; ! 718: lispval Istsrch(); ! 719: lispval debugmode; ! 720: ! 721: val_loop: ! 722: if(! VALID(a)) { ! 723: debugmode = Istsrch(matom("debugging"))->d.cdr->d.cdr->d.cdr; ! 724: if(debugmode != nil) { ! 725: printf("<printr:bad lisp data: 0x%x>\n",a); ! 726: error("Bad lisp data encountered by printr", FALSE); ! 727: } else { ! 728: a = badst; ! 729: printf("<printr:bad lisp data: 0x%x>",a); ! 730: return; ! 731: } ! 732: } ! 733: ! 734: switch (TYPE(a)) ! 735: { ! 736: ! 737: ! 738: case UNBO: fputs("<UNBOUND>",useport); ! 739: break; ! 740: ! 741: case VALUE: fputs("(ptr to)",useport); ! 742: a = a->l; ! 743: goto val_loop; ! 744: ! 745: case INT: fprintf(useport,"%d",a->i); ! 746: break; ! 747: ! 748: case DOUB: { char buf[64]; ! 749: lfltpr(buf,a->r); ! 750: fputs(buf,useport); ! 751: } ! 752: break; ! 753: ! 754: case PORT: { lispval cp; ! 755: if((cp = ioname[PN(a->p)]) == nil) ! 756: fputs("%$unopenedport",useport); ! 757: else fprintf(useport,"%%%s",cp); ! 758: } ! 759: break; ! 760: ! 761: case HUNK2: ! 762: case HUNK4: ! 763: case HUNK8: ! 764: case HUNK16: ! 765: case HUNK32: ! 766: case HUNK64: ! 767: case HUNK128: ! 768: if(plevel == 0) ! 769: { ! 770: fputs("%",useport); ! 771: break; ! 772: } ! 773: hsize = 2 << HUNKSIZE(a); ! 774: fputs("{", useport); ! 775: plevel--; ! 776: printr(a->h.hunk[0], useport); ! 777: curplength--; ! 778: for (i=1; i < hsize; i++) ! 779: { ! 780: if (a->h.hunk[i] == hunkfree) ! 781: break; ! 782: if (curplength-- == 0) ! 783: { ! 784: fputs(" ...",useport); ! 785: break; ! 786: } ! 787: else ! 788: { ! 789: fputs(" ", useport); ! 790: printr(a->h.hunk[i], useport); ! 791: } ! 792: } ! 793: fputs("}", useport); ! 794: plevel++; ! 795: break; ! 796: ! 797: case VECTOR: ! 798: chstr = "vector"; ! 799: quot = 4; /* print out # of longwords */ ! 800: goto veccommon; ! 801: ! 802: case VECTORI: ! 803: chstr = "vectori"; ! 804: quot = 1; ! 805: veccommon: ! 806: /* print out 'vector' or 'vectori' except in ! 807: * these circumstances: ! 808: * property is a symbol, in which case print ! 809: * the symbol's pname ! 810: * property is a list with a 'print' property, ! 811: * in which case it is funcalled to print the ! 812: * vector ! 813: */ ! 814: if(a->v.vector[VPropOff] != nil) ! 815: { ! 816: if ((i=TYPE(a->v.vector[VPropOff])) == ATOM) ! 817: { ! 818: chstr = a->v.vector[VPropOff]->a.pname; ! 819: } ! 820: else if ((i == DTPR) && vectorpr(a,useport)) ! 821: { ! 822: break; /* printed by vectorpr */ ! 823: } ! 824: else if ((i == DTPR) ! 825: && (a->v.vector[VPropOff]->d.car != nil) ! 826: && TYPE(a->v.vector[VPropOff]->d.car) ! 827: == ATOM) ! 828: { ! 829: chstr = a->v.vector[VPropOff]->d.car->a.pname; ! 830: } ! 831: } ! 832: fprintf(useport,"%s[%d]", ! 833: chstr, a->vl.vectorl[VSizeOff]/quot); ! 834: break; ! 835: ! 836: case ARRAY: fputs("array[",useport); ! 837: printr(a->ar.length,useport); ! 838: fputs("]",useport); ! 839: break; ! 840: ! 841: case BCD: fprintf(useport,"#%X-",a->bcd.start); ! 842: printr(a->bcd.discipline,useport); ! 843: break; ! 844: ! 845: case OTHER: fprintf(useport,"#Other-%X",a); ! 846: break; ! 847: ! 848: case SDOT: pbignum(a,useport); ! 849: break; ! 850: ! 851: case DTPR: if(plevel==0) ! 852: { ! 853: fputs("&",useport); ! 854: break; ! 855: } ! 856: plevel--; ! 857: if(a->d.car==quota && a->d.cdr!=nil ! 858: && a->d.cdr->d.cdr==nil) { ! 859: putc('\'',useport); ! 860: printr(a->d.cdr->d.car,useport); ! 861: plevel++; ! 862: break; ! 863: } ! 864: putc('(',useport); ! 865: curplength--; ! 866: morelist: printr(a->d.car,useport); ! 867: if ((a = a->d.cdr) != nil) ! 868: { ! 869: if(curplength-- == 0) ! 870: { ! 871: fputs(" ...",useport); ! 872: goto out; ! 873: } ! 874: putc(' ',useport); ! 875: if (TYPE(a) == DTPR) goto morelist; ! 876: fputs(". ",useport); ! 877: printr(a,useport); ! 878: } ! 879: out: ! 880: fputc(')',useport); ! 881: plevel++; ! 882: break; ! 883: ! 884: case STRNG: strflag = TRUE; ! 885: Idqc = Xsdc; ! 886: ! 887: case ATOM: { ! 888: char *front, *temp, first; int clean; ! 889: temp = front = (strflag ? ((char *) a) : a->a.pname); ! 890: if(Idqc==0) Idqc = Xdqc; ! 891: ! 892: if(Idqc) { ! 893: clean = first = *temp; ! 894: first &= 0177; ! 895: switch(QUTMASK & ctable[first]) { ! 896: case QWNFRST: ! 897: case QALWAYS: ! 898: clean = 0; break; ! 899: case QWNUNIQ: ! 900: if(temp[1]==0) clean = 0; ! 901: } ! 902: if (first=='-'||first=='+') temp++; ! 903: if(synclass(ctable[*temp])==VNUM) clean = 0; ! 904: while (clean && *temp) { ! 905: if((ctable[*temp]&QUTMASK)==QALWAYS) ! 906: clean = 0; ! 907: else if(uctolc && (isupper(*temp))) ! 908: clean = 0; ! 909: temp++; ! 910: } ! 911: if (clean && !strflag) ! 912: fputs(front,useport); ! 913: else { ! 914: putc(Idqc,useport); ! 915: for(temp=front;*temp;temp++) { ! 916: if( *temp==Idqc ! 917: || (synclass(ctable[*temp])) == CESC) ! 918: putc(Xesc,useport); ! 919: putc(*temp,useport); ! 920: } ! 921: putc(Idqc,useport); ! 922: } ! 923: ! 924: } else { ! 925: register char *cp = front; ! 926: int handy = ctable[*cp & 0177]; ! 927: ! 928: if(synclass(handy)==CNUM) ! 929: putc(Xesc,useport); ! 930: else switch(handy & QUTMASK) { ! 931: case QWNUNIQ: ! 932: if(cp[1]==0) putc(Xesc,useport); ! 933: break; ! 934: case QWNFRST: ! 935: case QALWAYS: ! 936: putc(Xesc,useport); ! 937: } ! 938: for(; *cp; cp++) { ! 939: if((ctable[*cp]& QUTMASK)==QALWAYS) ! 940: putc(Xesc,useport); ! 941: putc(*cp,useport); ! 942: } ! 943: } ! 944: } ! 945: } ! 946: } ! 947: ! 948: /* -- vectorpr ! 949: * (perhaps) print out vector specially ! 950: * this is called with a vector whose property list begins with ! 951: * a list. We search for the 'print' property and if it exists, ! 952: * funcall the print function with two args: the vector and the port. ! 953: * We return TRUE iff we funcalled the function, else we return FALSE ! 954: * to have the standard printing done ! 955: */ ! 956: ! 957: vectorpr(vec,port) ! 958: register lispval vec; ! 959: FILE *port; ! 960: { ! 961: register lispval handy; ! 962: int svplevel = plevel; /* save these global values */ ! 963: int svplength = plength; ! 964: Savestack(2); ! 965: ! 966: ! 967: for ( handy = vec->v.vector[VPropOff]->d.cdr ! 968: ; handy != nil; handy = handy->d.cdr->d.cdr) ! 969: { ! 970: if (handy->d.car == Vprintsym) ! 971: { ! 972: lbot = np; ! 973: protect(handy->d.cdr->d.car); /* function to call */ ! 974: protect(vec); ! 975: protect(P(port)); ! 976: Lfuncal(); ! 977: plevel = svplevel; /* restore globals */ ! 978: plength = svplength; ! 979: Restorestack(); ! 980: return(TRUE); /* did the call */ ! 981: } ! 982: } ! 983: Restorestack(); ! 984: return(FALSE); /* nothing printed */ ! 985: } ! 986: ! 987: ! 988: ! 989: ! 990: ! 991: ! 992: lfltpr(buf,val) /* lisp floating point printer */ ! 993: char *buf; ! 994: double val; ! 995: { ! 996: register char *cp1; char *sprintf(); ! 997: ! 998: sprintf(buf,(char *)Vfloatformat->a.clb,val); ! 999: for(cp1 = buf; *cp1; cp1++) ! 1000: if(*cp1=='.'|| *cp1=='E' || *cp1 == 'e') return; ! 1001: ! 1002: /* if we are here, there was no dot, so the number was ! 1003: an integer. Furthermore, cp1 already points to the ! 1004: end of the string. */ ! 1005: ! 1006: *cp1++ = '.'; ! 1007: *cp1++ = '0'; ! 1008: *cp1++ = 0; ! 1009: } ! 1010: ! 1011: ! 1012: /* dmpport ****************************************************************/ ! 1013: /* outputs buffer indicated by first argument whether full or not */ ! 1014: ! 1015: dmpport(useport) ! 1016: FILE *useport; ! 1017: { ! 1018: fflush(useport); ! 1019: } ! 1020: ! 1021: /* protect and unprot moved to eval.c (whr) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.