|
|
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.