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