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