|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <sys/types.h> ! 3: #include <sys/stat.h> ! 4: #include "dev.h" ! 5: #include "pp.h" ! 6: ! 7: /* ! 8: * ALL geometry in device units ! 9: */ ! 10: ! 11: #define B_MASK 0377 /* because we can't always say unsigned char */ ! 12: #define DEFSIZE 10 /* point size of normal text (only used for vert. motion) */ ! 13: #define PAGELENGTH (11*dev.res) ! 14: #define PAGEWIDTH (8*dev.res) ! 15: struct dev dev; ! 16: struct Font font; ! 17: char fontdir[]="/usr/lib/font"; ! 18: char *devname="202"; ! 19: char *fontname=0; ! 20: unsigned char width[B_MASK+1]; ! 21: char ligs[B_MASK+1]; ! 22: char codes[B_MASK+1]; ! 23: char fitab[B_MASK+1]; ! 24: unsigned char special[96]; ! 25: int miwidth; ! 26: int havespecial=0; ! 27: int pageno, hpos, vpos; ! 28: int margin, vspace; ! 29: char curfunc[128]; ! 30: char idchars[]="_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; ! 31: char *curfile; ! 32: char filetime[32]; ! 33: int functionmarked; ! 34: typedef struct{ ! 35: int variant; /* ROMAN, ITALIC, BOLD or BLACK */ ! 36: short size; /* point size */ ! 37: unsigned char width[96]; /* width tables */ ! 38: }Ftab; ! 39: #define ROMAN 0 ! 40: #define ITALIC 1 ! 41: #define BOLD 2 ! 42: #define BLACK 3 ! 43: Ftab ftab[]={ ! 44: #define R9 0 ! 45: {ROMAN, 9}, ! 46: #define R10 1 ! 47: {ROMAN, 10}, ! 48: #define R14 2 ! 49: {ROMAN, 14}, ! 50: #define I9 3 ! 51: {ITALIC, 9}, ! 52: #define I10 4 ! 53: {ITALIC, 10}, ! 54: #define I14 5 ! 55: {ITALIC, 14}, ! 56: #define B9 6 ! 57: {BOLD, 9}, ! 58: #define B10 7 ! 59: {BOLD, 10}, ! 60: #define B14 8 ! 61: {BOLD, 14}, ! 62: {0, 0} /* 0 size marks end */ ! 63: }; ! 64: Ftab *curfont=ftab; ! 65: main(argc, argv) ! 66: char *argv[]; ! 67: { ! 68: struct stat statbuf; ! 69: long timebuf; ! 70: char *ctime(); ! 71: char *title=0; ! 72: --argc; argv++; ! 73: while(argc>0 && argv[0][0]=='-'){ ! 74: switch(argv[0][1]){ ! 75: default: ! 76: error("usage: pp [-t\"Title\"] [-T202] [-fE] [-k] [files]", (char *)0); ! 77: case 'k': ! 78: ckeywords(&argv[0][2]); ! 79: break; ! 80: case 'f': ! 81: fontname= &argv[0][2]; ! 82: break; ! 83: case 'b': ! 84: blacken(); ! 85: break; ! 86: case 't': ! 87: title= &argv[0][2]; ! 88: break; ! 89: case 'T': ! 90: devname= &argv[0][2]; ! 91: break; ! 92: } ! 93: --argc; argv++; ! 94: } ! 95: if(fontname==0){ ! 96: fontname="Memphis"; ! 97: blacken(); ! 98: } ! 99: load(); ! 100: if(title){ ! 101: time(&timebuf); ! 102: coverpage(title, ctime(&timebuf)); ! 103: } ! 104: if(argc<=0){ ! 105: curfile="<stdin>"; ! 106: time(&timebuf); ! 107: strcpy(filetime, ctime(&timebuf)+4); ! 108: process(0); ! 109: }else while(argc-->0){ ! 110: stat(*argv, &statbuf); ! 111: strcpy(filetime, ctime(&statbuf.st_mtime)+4); ! 112: process(Open(curfile= *argv++)); ! 113: } ! 114: printf("x trailer\nV0\nx stop\n"); ! 115: return 0; ! 116: } ! 117: blacken(){ ! 118: register i; ! 119: for(i=B9; i<=B14; i++) ! 120: ftab[i].variant=BLACK; ! 121: } ! 122: char *fontexcep[][4]={ ! 123: /* roman italic bold black indices match #defines above */ ! 124: "R", "I", "B", "B", /* Times Roman */ ! 125: "PA", "PI", "PB", "PB", /* Palatino */ ! 126: "H", "HI", "HB", "HK", /* Helvetica */ ! 127: "CW", "CS", "CS", "CS", /* constant width Courier */ ! 128: "PO", "PI", "PB", "PX", /* constant width */ ! 129: 0 ! 130: }; ! 131: char *suffix[]={ ! 132: "", "I", "B", "BK" ! 133: }; ! 134: char * ! 135: fonttag(variant){ ! 136: static char buf[512]; ! 137: register i; ! 138: for(i=0;fontexcep[i][0];i++) ! 139: if(strcmp(fontexcep[i][0], fontname)==0) ! 140: return fontexcep[i][variant]; ! 141: sprintf(buf, "%s%s", fontname, suffix[variant]); ! 142: return buf; ! 143: } ! 144: load(){ ! 145: register fd, i, j, mi; ! 146: register Ftab *f; ! 147: register char *s; ! 148: char file[64]; ! 149: char buf[600]; /* should be enough (gulp) */ ! 150: long lseek(); ! 151: sprintf(file, "%s/dev%s/DESC.out", fontdir, devname); ! 152: fd=Open(file); ! 153: Read(file, fd, &dev, sizeof dev); ! 154: /* Find \(mi to remember its width */ ! 155: if(lseek(fd, (dev.nsizes+1+dev.nchtab)*sizeof(short), 1)==-1L) ! 156: error("device file incomplete", file); ! 157: j=read(fd, buf, sizeof buf); ! 158: for(s=buf,mi=0; j>0 && strcmp(s, "mi")!=0; mi++){ ! 159: s+=strlen(s)+1; ! 160: j-=strlen(s)+1; ! 161: } ! 162: if(j<=0) ! 163: error("can't find minus in special font on", devname); ! 164: close(fd); ! 165: printf("x T %s\n", devname); ! 166: printf("x res %d %d %d\n", dev.res, dev.hor, dev.vert); ! 167: printf("x init\n"); ! 168: sprintf(file, "%s/dev%s/S.out", fontdir, devname); ! 169: readfont(file); ! 170: printf("x font %d S\n", dev.nfonts); /* Guess? */ ! 171: setwidths(special, dev.unitwidth); ! 172: havespecial=1; ! 173: miwidth=width[fitab[mi+128-32]]; ! 174: margin=dev.res/2; /* 1/2 inch */ ! 175: vspace=DEFSIZE*dev.res/72; /* units per line */ ! 176: for(f=ftab; f->size; ){ ! 177: sprintf(file, "%s/dev%s/%s.out", fontdir, devname, ! 178: fonttag(f->variant)); ! 179: readfont(file); ! 180: printf("x font %d %s\n", (f-ftab)/3+1, fonttag(f->variant)); ! 181: for(j=0; j<3; j++, f++) ! 182: setwidths(f->width, f->size); ! 183: } ! 184: } ! 185: setwidths(wt, size) ! 186: register char *wt; ! 187: { ! 188: register i, n; ! 189: for(i=0; i<96; i++, wt++){ ! 190: if(n=fitab[i]) ! 191: n=width[n]; ! 192: else if(havespecial) ! 193: n=special[i]; ! 194: *wt=size*n/dev.unitwidth; ! 195: } ! 196: } ! 197: readfont(file) ! 198: char *file; ! 199: { ! 200: register fd; ! 201: fd=Open(file); ! 202: Read(file, fd, &font, sizeof font); ! 203: Read(file, fd, width, font.nwfont&B_MASK); ! 204: Read(file, fd, ligs, font.nwfont&B_MASK); ! 205: Read(file, fd, codes, font.nwfont&B_MASK); ! 206: /*Read(file, fd, fitab, dev.nchtab+128-32);*/ ! 207: read(fd, fitab, dev.nchtab+128-32); ! 208: close(fd); ! 209: } ! 210: coverpage(s, t) ! 211: char *s, *t; ! 212: { ! 213: printf("p0\nV%d\n", dev.res*4); /* 3 inches down */ ! 214: center(&ftab[B14], s); ! 215: printf("v%d\n", dev.res); /* another inch */ ! 216: center(&ftab[I9], t); ! 217: } ! 218: Open(s) ! 219: char *s; ! 220: { ! 221: register f=open(s, 0); ! 222: if(f<0) ! 223: error("can't open", s); ! 224: return f; ! 225: } ! 226: Read(s, f, a, n) ! 227: char *s, *a; ! 228: { ! 229: if(read(f, a, n)!=n) ! 230: error("read error on file", s); ! 231: } ! 232: error(s, t) ! 233: char *s, *t; ! 234: { ! 235: fprintf(stderr, "pp: %s %s\n", s, t); ! 236: exit(1); ! 237: } ! 238: char * ! 239: extractfn(s) ! 240: register char *s; ! 241: { ! 242: extern char *strrchr(), *strchr(); ! 243: register char *t=strrchr(s, '('), *u; ! 244: if(t==0) ! 245: error("extract can't find function in", s); ! 246: while(strchr(idchars, *t)==0) ! 247: if(t<=s) ! 248: return ""; ! 249: else ! 250: --t; ! 251: for(u=t; u>=s && strchr(idchars, *u); --u) ! 252: ; ! 253: strncpy(curfunc, u+1, t-u); ! 254: curfunc[t-u]=0; ! 255: return curfunc; ! 256: } ! 257: /* ! 258: * function name should not be in italics ! 259: */ ! 260: process(fd) ! 261: register fd; ! 262: { ! 263: register char *s; ! 264: register unsigned char *w; ! 265: register type; ! 266: register Ftab *f=0, *of; ! 267: register c; ! 268: char buf[32]; ! 269: fileno(stdin)=fd; /* cough */ ! 270: pageno=0; ! 271: topofpage(); ! 272: curfont= &ftab[R10]; ! 273: curfunc[0]=0; ! 274: while(type=yylex()){ ! 275: of=f; ! 276: /* ! 277: * Appropriate font switches, etc. ! 278: */ ! 279: switch(type){ ! 280: case FUNCTION: ! 281: rjust(&ftab[I14], extractfn(yytext)); ! 282: functionmarked=1; ! 283: case OTHER: ! 284: f= &ftab[R10]; ! 285: break; ! 286: case COMMENT:{ ! 287: Ftab *oldfont; ! 288: /* gotta do this in place, sigh */ ! 289: oldfont = curfont; ! 290: curfont = f= &ftab[I10]; ! 291: w=f->width; ! 292: drawstr(f, yytext); ! 293: printf("f2 s10\n"); ! 294: for(;;){ ! 295: outchar(f, c=yyinput()); ! 296: if(c==0) ! 297: break; ! 298: if(c=='*'){ ! 299: GotStar: ! 300: outchar(f, c=yyinput()); ! 301: if(c=='/') ! 302: break; ! 303: if(c=='*') ! 304: goto GotStar; ! 305: } ! 306: if(c=='\n'){ ! 307: GotNewline: ! 308: newline(); ! 309: while((c=yyinput())=='\t') ! 310: hpos=tabstop(w); ! 311: if(c==' ') ! 312: printf("H%d\n", hpos+=w['/'-32]); ! 313: else if(c=='\n') ! 314: goto GotNewline; ! 315: else{ ! 316: printf("H%d\n", hpos); ! 317: outchar(f, c); ! 318: if(c=='*') ! 319: goto GotStar; ! 320: } ! 321: } ! 322: } ! 323: curfont=f=oldfont; ! 324: printf("f%d s%d\n", (f-ftab)/3+1, f->size); ! 325: continue; ! 326: } ! 327: case KEYWORD: ! 328: f= &ftab[B10]; ! 329: break; ! 330: } ! 331: if(functionmarked==0){ ! 332: if(curfunc[0]){ ! 333: sprintf(buf, "...%s", curfunc); ! 334: rjust(&ftab[I9], buf); ! 335: } ! 336: functionmarked=1; ! 337: } ! 338: if(of!=f){ /* font switch */ ! 339: printf("f%d s%d\n", (f-ftab)/3+1, f->size); ! 340: curfont=f; ! 341: } ! 342: w=f->width; ! 343: /* ! 344: * Draw them. ! 345: */ ! 346: for(s=yytext; *s; s++){ ! 347: switch(*s){ ! 348: case '\n': ! 349: newline(); ! 350: break; ! 351: case '\f': ! 352: vpos = PAGELENGTH; ! 353: newline(); ! 354: break; ! 355: case ' ': ! 356: printf("h%d\n", w['n'-32]); ! 357: hpos+=w['n'-32]; ! 358: break; ! 359: case '\t': ! 360: hpos=tabstop(w); ! 361: printf("H%d\n", hpos); ! 362: break; ! 363: case '-': ! 364: printf("Cmi h%d\n", miwidth*f->size/dev.unitwidth); ! 365: hpos+=miwidth*f->size/dev.unitwidth; ! 366: break; ! 367: default: ! 368: printf("c%c h%d\n", *s, w[*s-32]); ! 369: hpos+=w[*s-32]; ! 370: break; ! 371: } ! 372: } ! 373: } ! 374: bottomofpage(); ! 375: close(fd); ! 376: } ! 377: newline(){ ! 378: if((vpos+=vspace)>PAGELENGTH-margin-3*vspace){ /* new page */ ! 379: bottomofpage(); ! 380: topofpage(); ! 381: }else{ ! 382: printf("n\n"); ! 383: printf("v%d\n", vspace); ! 384: } ! 385: printf("H%d\n", hpos=margin); ! 386: } ! 387: topofpage(){ ! 388: printf("p%d\n", pageno++); ! 389: hpos=margin; ! 390: vpos=margin; ! 391: printf("V%d\n", vpos); ! 392: printf("H%d\n", hpos); ! 393: drawstr(&ftab[B14], curfile); ! 394: rjust(&ftab[B14], curfile); ! 395: printf("v%d\n", 3*vspace); ! 396: vpos+=3*vspace; ! 397: functionmarked=0; ! 398: } ! 399: bottomofpage(){ ! 400: char buf[256]; ! 401: printf("H%d\n", margin); ! 402: printf("V%d\n", PAGELENGTH-margin); ! 403: drawstr(&ftab[I9], filetime); ! 404: sprintf(buf, "Page %d of %s", pageno, curfile); ! 405: rjust(&ftab[I9], buf); ! 406: } ! 407: strwidth(f, s) ! 408: Ftab *f; ! 409: register char *s; ! 410: { ! 411: register unsigned char *w=f->width; ! 412: register n=0; ! 413: while(*s){ ! 414: if(*s==' ') ! 415: n+=w['n'-32]; ! 416: else if(*s>' ') ! 417: n+=w[*s-32]; ! 418: s++; ! 419: } ! 420: return n; ! 421: } ! 422: rjust(f, s) ! 423: register Ftab *f; ! 424: register char *s; ! 425: { ! 426: printf("H%d\n", PAGEWIDTH-margin-strwidth(f, s)); ! 427: drawstr(f, s); ! 428: printf("H%d\n", hpos); ! 429: } ! 430: center(f, s) ! 431: register Ftab *f; ! 432: register char *s; ! 433: { ! 434: printf("H%d\n", (PAGEWIDTH-margin-strwidth(f, s))/2); ! 435: drawstr(f, s); ! 436: printf("H%d\n", hpos); ! 437: } ! 438: drawstr(f, s) ! 439: register Ftab *f; ! 440: register char *s; ! 441: { ! 442: register c; ! 443: printf("f%d s%d\n", (f-ftab)/3+1, f->size); ! 444: while(c= *s++) /* assignment = */ ! 445: if(c==' ') ! 446: printf("h%d\n", f->width['n'-32]); ! 447: else ! 448: printf("c%c h%d\n", c, f->width[c-32]); ! 449: printf("f%d s%d\n", (curfont-ftab)/3+1, curfont->size); ! 450: } ! 451: outchar(f, c) ! 452: register Ftab *f; ! 453: register c; ! 454: { ! 455: register w; ! 456: if(c==' ') ! 457: printf("h%d\n", w=f->width['n'-32]); ! 458: else ! 459: printf("c%c h%d\n", c, w=f->width[c-32]); ! 460: hpos+=w; ! 461: } ! 462: tabstop(w) ! 463: register unsigned char *w; ! 464: { ! 465: register c, block; ! 466: ! 467: block = w['i'-32] == w['m'-32]? (8*w['n'-32]):(dev.res/2); ! 468: c = margin + block*((hpos-margin+block-1)/block); ! 469: if(hpos == c) ! 470: c += block; ! 471: return(c); ! 472: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.