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