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