]> git.lyx.org Git - lyx.git/blob - 3rdparty/dtl/dv2dt.c
Update sk.po
[lyx.git] / 3rdparty / dtl / dv2dt.c
1 /* dv2dt - convert DVI file to human-readable "DTL" format.
2    
3    This file is public domain.
4    Originally written 1995, Geoffrey Tobin.
5    The author has expressed the hope that any modification will retain enough content to remain useful. He would also appreciate being acknowledged as the original author in the documentation.
6    This declaration added 2008/11/14 by Clea F. Rees with the permission of Geoffrey Tobin.
7
8    - (ANSI C) version 0.6.0 - 17:54 GMT +11  Wed 8 March 1995
9    - author:  Geoffrey Tobin    ecsgrt@luxor.latrobe.edu.au
10    - patch:  Michal Tomczak-Jaegermann   ntomczak@vm.ucs.ualberta.ca
11    - Reference:  "The DVI Driver Standard, Level 0",
12                  by  The TUG DVI Driver Standards Committee.
13                  Appendix A, "Device-Independent File Format".
14 */
15
16 /* unix version; read from stdin, write to stdout, by default. */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <ctype.h>
22
23 #include "dtl.h"
24
25 #define PRINT_BCOM   if (group) fprintf (dtl, "%s", BCOM)
26 #define PRINT_ECOM   if (group) fprintf (dtl, "%s", ECOM)
27
28 /*
29   operation's:
30      opcode,
31      name,
32      number of args,
33      string of arguments.
34 */
35 struct op_info_st {int code; char * name; int nargs; char * args; };
36
37 typedef  struct op_info_st  op_info;
38
39 /*
40   table's:
41      name,
42      first opcode,
43      last opcode,
44      pointer to opcode info.
45 */
46 struct op_table_st {char * name; int first; int last; op_info * list; };
47
48 typedef  struct op_table_st  op_table;
49
50 /* Table for opcodes 128 to 170 inclusive. */
51
52 op_info  op_info_128_170 [] =
53 {
54   {128, "s1", 1, "1"},
55   {129, "s2", 1, "2"},
56   {130, "s3", 1, "3"},
57   {131, "s4", 1, "-4"},
58   {132, "sr", 2, "-4 -4"},
59   {133, "p1", 1, "1"},
60   {134, "p2", 1, "2"},
61   {135, "p3", 1, "3"},
62   {136, "p4", 1, "-4"},
63   {137, "pr", 2, "-4 -4"},
64   {138, "nop", 0, ""},
65   {139, "bop", 11, "-4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4"},
66   {140, "eop", 0, ""},
67   {141, "[", 0, ""},
68   {142, "]", 0, ""},
69   {143, "r1", 1, "-1"},
70   {144, "r2", 1, "-2"},
71   {145, "r3", 1, "-3"},
72   {146, "r4", 1, "-4"},
73   {147, "w0", 0, ""},
74   {148, "w1", 1, "-1"},
75   {149, "w2", 1, "-2"},
76   {150, "w3", 1, "-3"},
77   {151, "w4", 1, "-4"},
78   {152, "x0", 0, ""},
79   {153, "x1", 1, "-1"},
80   {154, "x2", 1, "-2"},
81   {155, "x3", 1, "-3"},
82   {156, "x4", 1, "-4"},
83   {157, "d1", 1, "-1"},
84   {158, "d2", 1, "-2"},
85   {159, "d3", 1, "-3"},
86   {160, "d4", 1, "-4"},
87   {161, "y0", 0, ""},
88   {162, "y1", 1, "-1"},
89   {163, "y2", 1, "-2"},
90   {164, "y3", 1, "-3"},
91   {165, "y4", 1, "-4"},
92   {166, "z0", 0, ""},
93   {167, "z1", 1, "-1"},
94   {168, "z2", 1, "-2"},
95   {169, "z3", 1, "-3"},
96   {170, "z4", 1, "-4"}
97 };  /* op_info  op_info_128_170 [] */
98
99 op_table  op_128_170  =  {"op_128_170", 128, 170, op_info_128_170};
100
101 /* Table for font with 1 to 4 bytes (opcodes 235 to 238) inclusive. */
102
103 op_info  fnt_n [] =
104 {
105   {235, "f1", 1, "1"},
106   {236, "f2", 1, "2"},
107   {237, "f3", 1, "3"},
108   {238, "f4", 1, "-4"}
109 };  /* op_info  fnt_n [] */
110
111 op_table  fnt  =  {"f", 235, 238, fnt_n};
112
113
114 /* function prototypes */
115
116 int open_dvi ARGS((char * dvi_file, FILE ** dvi));
117 int open_dtl ARGS((char * dtl_file, FILE ** dtl));
118 int dv2dt ARGS((FILE * dvi, FILE * dtl));
119
120 COUNT wunsigned ARGS((int n,  FILE * dvi,  FILE * dtl));
121 COUNT wsigned   ARGS((int n,  FILE * dvi,  FILE * dtl));
122 S4 rsigned   ARGS((int n,  FILE * dvi));
123 U4 runsigned ARGS((int n,  FILE * dvi));
124
125 COUNT wtable ARGS((op_table table, int opcode, FILE * dvi, FILE * dtl));
126
127 COUNT setseq ARGS((int opcode, FILE * dvi, FILE * dtl));
128 Void setpchar ARGS((int charcode, FILE * dtl));
129 Void xferstring ARGS((int k, FILE * dvi, FILE * dtl));
130
131 COUNT special ARGS((FILE * dvi,  FILE * dtl,  int n));
132 COUNT fontdef ARGS((FILE * dvi,  FILE * dtl,  int n));
133 COUNT preamble  ARGS((FILE * dvi,  FILE * dtl));
134 COUNT postamble ARGS((FILE * dvi,  FILE * dtl));
135 COUNT postpost  ARGS((FILE * dvi,  FILE * dtl));
136
137
138 String program;  /* name of dv2dt program */
139
140 int
141 main
142 #ifdef STDC
143   (int argc,  char * argv[])
144 #else
145   (argc, argv)
146   int argc;
147   char * argv[];
148 #endif
149 {
150   FILE * dvi = stdin;
151   FILE * dtl = stdout;
152
153   /* Watch out:  C's standard library's string functions are dicey */
154   strncpy (program, argv[0], MAXSTRLEN);
155
156   if (argc > 1)
157     open_dvi (argv[1], &dvi);
158
159   if (argc > 2)
160     open_dtl (argv[2], &dtl);
161
162   dv2dt (dvi, dtl);
163
164   return 0;  /* OK */
165 }
166 /* end main */
167
168 int
169 open_dvi
170 #ifdef STDC
171   (char * dvi_file, FILE ** pdvi)
172 #else
173   (dvi_file, pdvi)
174   char * dvi_file;
175   FILE ** pdvi;
176 #endif
177 /* I:  dvi_file;  I:  pdvi;  O:  *pdvi. */
178 {
179   if (pdvi == NULL)
180   {
181     fprintf (stderr, "%s:  address of dvi variable is NULL.\n", program);
182     exit (1);
183   }
184
185   *pdvi = fopen (dvi_file, "rb");
186
187   if (*pdvi == NULL)
188   {
189     fprintf (stderr, "%s:  Cannot open \"%s\" for binary reading.\n",
190       program, dvi_file);
191     exit (1);
192   }
193
194   return 1;  /* OK */
195 }
196 /* open_dvi */
197
198 int
199 open_dtl
200 #ifdef STDC
201   (char * dtl_file, FILE ** pdtl)
202 #else
203   (dtl_file, pdtl)
204   char * dtl_file;
205   FILE ** pdtl;
206 #endif
207 /* I:  dtl_file;  I:  pdtl;  O:  *pdtl. */
208 {
209   if (pdtl == NULL)
210   {
211     fprintf (stderr, "%s:  address of dtl variable is NULL.\n", program);
212     exit (1);
213   }
214
215   *pdtl = fopen (dtl_file, "w");
216
217   if (*pdtl == NULL)
218   {
219     fprintf (stderr, "%s:  Cannot open \"%s\" for text writing.\n",
220       program, dtl_file);
221     exit (1);
222   }
223
224   return 1;  /* OK */
225 }
226 /* open_dtl */
227
228 int
229 dv2dt
230 #ifdef STDC
231   (FILE * dvi, FILE * dtl)
232 #else
233   (dvi, dtl)
234   FILE * dvi;
235   FILE * dtl;
236 #endif
237 {
238   int opcode;
239   COUNT count;  /* intended to count bytes to DVI file; as yet unused. */
240
241   PRINT_BCOM;
242   fprintf (dtl, "variety ");
243 /*  fprintf (dtl, BMES); */
244   fprintf (dtl, VARIETY);
245 /*  fprintf (dtl, EMES); */
246   PRINT_ECOM;
247   fprintf (dtl, "\n");
248
249   /* start counting DVI bytes */
250   count = 0;
251   while ((opcode = fgetc (dvi)) != EOF)
252   {
253     PRINT_BCOM;  /* start of command and parameters */
254     if (opcode < 0 || opcode > 255)
255     {
256       count += 1;
257       fprintf (stderr, "%s:  Non-byte from \"fgetc()\"!\n", program);
258       exit (1);
259     }
260     else if (opcode <= 127)
261     {
262       /* setchar commands */
263       /* count += 1; */
264       /* fprintf (dtl, "%s%d", SETCHAR, opcode); */
265       count +=
266       setseq (opcode, dvi, dtl);
267     }
268     else if (opcode >= 128 && opcode <= 170)
269     {
270       count +=
271       wtable (op_128_170, opcode, dvi, dtl);
272     }
273     else if (opcode >= 171 && opcode <= 234)
274     {
275       count += 1;
276       fprintf (dtl, "%s%d", FONTNUM, opcode - 171);
277     }
278     else if (opcode >= 235 && opcode <= 238)
279     {
280       count +=
281       wtable (fnt, opcode, dvi, dtl);
282     }
283     else if (opcode >= 239 && opcode <= 242)
284     {
285       count +=
286       special (dvi, dtl, opcode - 238);
287     }
288     else if (opcode >= 243 && opcode <= 246)
289     {
290       count +=
291       fontdef (dvi, dtl, opcode - 242);
292     }
293     else if (opcode == 247)
294     {
295       count +=
296       preamble (dvi, dtl);
297     }
298     else if (opcode == 248)
299     {
300       count +=
301       postamble (dvi, dtl);
302     }
303     else if (opcode == 249)
304     {
305       count +=
306       postpost (dvi, dtl);
307     }
308     else if (opcode >= 250 && opcode <= 255)
309     {
310       count += 1;
311       fprintf (dtl, "opcode%d", opcode);
312     }
313     else
314     {
315       count += 1;
316       fprintf (stderr, "%s:  unknown byte.\n", program);
317       exit (1);
318     }
319     PRINT_ECOM;  /* end of command and parameters */
320     fprintf (dtl, "\n");
321     if (fflush (dtl) == EOF)
322     {
323       fprintf (stderr, "%s:  fflush on dtl file gave write error!\n", program);
324       exit (1);
325     }
326   } /* end while */
327
328   return 1;  /* OK */
329 }
330 /* dv2dt */
331
332
333 COUNT
334 wunsigned
335 #ifdef STDC
336   (int n, FILE * dvi, FILE * dtl)
337 #else
338   (n, dvi, dtl)
339   int n;
340   FILE * dvi;
341   FILE * dtl;
342 #endif
343 {
344   U4 unum;
345
346   fprintf (dtl, " ");
347   unum = runsigned (n, dvi);
348   fprintf (dtl, UF4, unum);
349   return n;
350 }
351 /* end wunsigned */
352
353 COUNT
354 wsigned
355 #ifdef STDC
356   (int n, FILE * dvi, FILE * dtl)
357 #else
358   (n, dvi, dtl)
359   int n;
360   FILE * dvi;
361   FILE * dtl;
362 #endif
363 {
364   S4 snum;
365
366   fprintf (dtl, " ");
367   snum = rsigned (n, dvi);
368   fprintf (dtl, SF4, snum);
369   return n;
370 }
371 /* end wsigned */
372
373 U4
374 runsigned
375 #ifdef STDC
376   (int n,  FILE * dvi)
377 #else
378   (n, dvi)
379   int n;
380   FILE * dvi;
381 #endif
382 /* read 1 <= n <= 4 bytes for an unsigned integer from dvi file */
383 /* DVI format uses Big-endian storage of numbers. */
384 {
385   U4 integer;
386   int ibyte = 0;
387   int i;
388
389   if (n < 1 || n > 4)
390   {
391     fprintf (stderr,
392       "%s:  runsigned() asked for %d bytes.  Must be 1 to 4.\n", program, n);
393     exit (1);
394   }
395
396   /* Following calculation works iff storage is big-endian. */
397   integer = 0;
398   for (i = 0; i < n; i++)
399   {
400     integer *= 256;
401     ibyte = fgetc (dvi);
402     integer += ibyte;
403   }
404
405   return integer;
406 }
407 /* end runsigned */
408
409 S4
410 rsigned
411 #ifdef STDC
412   (int n,  FILE * dvi)
413 #else
414   (n, dvi)
415   int n;
416   FILE * dvi;
417 #endif
418 /* read 1 <= n <= 4 bytes for a signed integer from dvi file */
419 /* DVI format uses Big-endian storage of numbers. */
420 {
421   S4 integer;
422   int ibyte = 0;
423   int i;
424
425   if (n < 1 || n > 4)
426   {
427     fprintf (stderr,
428       "%s:  rsigned() asked for %d bytes.  Must be 1 to 4.\n", program, n);
429     exit (1);
430   }
431
432   /* Following calculation works iff storage is big-endian. */
433   integer = 0;
434   for (i = 0; i < n; i++)
435   {
436     integer *= 256;
437     ibyte = fgetc (dvi);
438     /* Big-endian implies sign byte is first byte. */
439     if (i == 0 && ibyte >= 128)
440     {
441       ibyte -= 256;
442     }
443     integer += ibyte;
444   }
445
446   return integer;
447 }
448 /* end rsigned */
449
450 COUNT
451 wtable
452 #ifdef STDC
453   (op_table table, int opcode, FILE * dvi, FILE * dtl)
454 #else
455   (table, opcode, dvi, dtl)
456   op_table table;
457   int opcode;
458   FILE * dvi;
459   FILE * dtl;
460 #endif
461 /* write command with given opcode in given table */
462 /* return number of DVI bytes in this command */
463 {
464   op_info op;  /* pointer into table of operations and arguments */
465   COUNT bcount = 0;  /* number of bytes in arguments of this opcode */
466   String args;  /* arguments string */
467   int i;  /* count of arguments read from args */
468   int pos;  /* position in args */
469
470   /* Defensive programming. */
471   if (opcode < table.first || opcode > table.last)
472   {
473     fprintf (stderr,
474       "%s: opcode %d is outside table %s [ %d to %d ] !\n",
475       program, opcode, table.name, table.first, table.last);
476     exit (1);
477   }
478
479   op = table.list [opcode - table.first];
480
481   /* Further defensive programming. */
482   if (op.code != opcode)
483   {
484     fprintf (stderr, "%s: internal table %s wrong!\n", program, table.name);
485     exit (1);
486   }
487
488   bcount = 1;
489   fprintf (dtl, "%s", op.name);
490
491   /* NB:  sscanf does an ungetc, */
492   /*      so args must be writable. */
493
494   strncpy (args, op.args, MAXSTRLEN);
495
496   pos = 0;
497   for (i = 0; i < op.nargs; i++)
498   {
499     int argtype;  /* sign and number of bytes in current argument */
500     int nconv;  /* number of successful conversions from args */
501     int nread;  /* number of bytes read from args */
502
503     nconv = sscanf (args + pos, "%d%n", &argtype, &nread);
504
505     /* internal consistency checks */
506     if (nconv != 1 || nread <= 0)
507     {
508       fprintf (stderr,
509         "%s: internal read of table %s failed!\n", program, table.name);
510       exit (1);
511     }
512
513     pos += nread;
514
515     bcount += ( argtype < 0 ?
516                wsigned  (-argtype, dvi, dtl) :
517                wunsigned (argtype, dvi, dtl)  ) ;
518   } /* end for */
519
520   return bcount;
521
522 }
523 /* wtable */
524
525 COUNT
526 setseq
527 #ifdef STDC
528   (int opcode, FILE * dvi, FILE * dtl)
529 #else
530   (opcode, dvi, dtl)
531   int opcode;
532   FILE * dvi;
533   FILE * dtl;
534 #endif
535 /* write a sequence of setchar commands */
536 /* return count of DVI bytes interpreted into DTL */
537 {
538   int charcode = opcode;  /* fortuitous */
539   int ccount = 0;
540
541   if (!isprint (charcode))
542   {
543     ccount = 1;
544     fprintf (dtl, "%s%02X", SETCHAR, opcode);
545   }
546   else
547   {
548     /* start of sequence of font characters */
549     fprintf (dtl, BSEQ);
550
551     /* first character */
552     ccount = 1;
553     setpchar (charcode, dtl);
554
555     /* subsequent characters */
556     while ((opcode = fgetc (dvi)) != EOF)
557     {
558       if (opcode < 0 || opcode > 127)
559       {
560         break;  /* not a setchar command, so sequence has ended */
561       }
562       charcode = opcode;  /* fortuitous */
563       if (!isprint (charcode))  /* not printable ascii */
564       {
565         break;  /* end of font character sequence, as for other commands */
566       }
567       else  /* printable ASCII */
568       {
569         ccount += 1;
570         setpchar (charcode, dtl);
571       }
572     }  /* end for loop */
573
574     /* prepare to reread opcode of next DVI command */
575     if (ungetc (opcode, dvi) == EOF)
576     {
577       fprintf (stderr, "setseq:  cannot push back a byte\n");
578       exit (1);
579     }
580
581     /* end of sequence of font characters */
582     fprintf (dtl, ESEQ);
583   }
584   return ccount;
585 }
586 /* setseq */
587
588 Void
589 setpchar
590 #ifdef STDC
591   (int charcode, FILE * dtl)
592 #else
593   (charcode, dtl)
594   int charcode;
595   FILE * dtl;
596 #endif
597 /* set printable character */
598 {
599   switch (charcode)
600   {
601     case ESC_CHAR:
602       fprintf (dtl, "%c", ESC_CHAR);
603       fprintf (dtl, "%c", ESC_CHAR);
604       break;
605     case QUOTE_CHAR:
606       fprintf (dtl, "%c", ESC_CHAR);
607       fprintf (dtl, "%c", QUOTE_CHAR);
608       break;
609     case BSEQ_CHAR:
610       fprintf (dtl, "%c", ESC_CHAR);
611       fprintf (dtl, "%c", BSEQ_CHAR);
612       break;
613     case ESEQ_CHAR:
614       fprintf (dtl, "%c", ESC_CHAR);
615       fprintf (dtl, "%c", ESEQ_CHAR);
616       break;
617     default:
618       fprintf (dtl, "%c", charcode);
619       break;
620   }
621 }
622 /* setpchar */
623
624 Void
625 xferstring
626 #ifdef STDC
627   (int k, FILE * dvi, FILE * dtl)
628 #else
629   (k, dvi, dtl)
630   int k;
631   FILE * dvi;
632   FILE * dtl;
633 #endif
634 /* copy string of k characters from dvi file to dtl file */
635 {
636   int i;
637   int ch;
638
639   fprintf (dtl, " ");
640   fprintf (dtl, "'");
641   for (i=0; i < k; i++)
642   {
643     ch = fgetc (dvi);
644     if (ch == ESC_CHAR || ch == EMES_CHAR)
645     {
646       fprintf (dtl, "%c", ESC_CHAR);
647     }
648     fprintf (dtl, "%c", ch);
649   }
650   fprintf (dtl, "'");
651 }
652 /* xferstring */
653
654 COUNT
655 special
656 #ifdef STDC
657   (FILE * dvi,  FILE * dtl,  int n)
658 #else
659   (dvi, dtl, n)
660   FILE * dvi;
661   FILE * dtl;
662   int n;
663 #endif
664 /* read special 1 .. 4 from dvi and write in dtl */
665 /* return number of DVI bytes interpreted into DTL */
666 {
667   U4  k;
668
669   if (n < 1 || n > 4)
670   {
671     fprintf (stderr, "%s:  special %d, range is 1 to 4.\n", program, n);
672     exit (1);
673   }
674
675   fprintf (dtl, "%s%d", SPECIAL, n);
676
677   /* k[n] = length of special string */
678   fprintf (dtl, " ");
679   k = runsigned (n, dvi);
680   fprintf (dtl, UF4, k);
681
682   /* x[k] = special string */
683   xferstring (k, dvi, dtl);
684
685   return (1 + n + k);
686 }
687 /* end special */
688
689 COUNT
690 fontdef
691 #ifdef STDC
692   (FILE * dvi,  FILE * dtl,  int n)
693 #else
694   (dvi,  dtl,  n)
695   FILE * dvi;
696   FILE * dtl;
697   int n;
698 #endif
699 /* read fontdef 1 .. 4 from dvi and write in dtl */
700 /* return number of DVI bytes interpreted into DTL */
701 {
702   U4 ku, c, s, d, a, l;
703   S4 ks;
704
705   if (n < 1 || n > 4)
706   {
707     fprintf (stderr, "%s:  font def %d, range is 1 to 4.\n", program, n);
708     exit (1);
709   }
710
711   fprintf (dtl, "%s%d", FONTDEF, n);
712
713   /* k[n] = font number */
714   fprintf (dtl, " ");
715   if (n == 4)
716   {
717     ks = rsigned (n, dvi);
718     fprintf (dtl, SF4, ks);
719   }
720   else
721   {
722     ku = runsigned (n, dvi);
723     fprintf (dtl, UF4, ku);
724   }
725
726   /* c[4] = checksum */
727   fprintf (dtl, " ");
728   c = runsigned (4, dvi);
729 #ifdef HEX_CHECKSUM
730   fprintf (dtl, XF4, c);
731 #else /* NOT HEX_CHECKSUM */
732   /* write in octal, to allow quick comparison with tftopl's output */
733   fprintf (dtl, OF4, c);
734 #endif
735
736   /* s[4] = scale factor */
737   fprintf (dtl, " ");
738   s = runsigned (4, dvi);
739   fprintf (dtl, UF4, s);
740
741   /* d[4] = design size */
742   fprintf (dtl, " ");
743   d = runsigned (4, dvi);
744   fprintf (dtl, UF4, d);
745
746   /* a[1] = length of area (directory) name */
747   a = runsigned (1, dvi);
748   fprintf (dtl, " ");
749   fprintf (dtl, UF4, a);
750
751   /* l[1] = length of font name */
752   l = runsigned (1, dvi);
753   fprintf (dtl, " ");
754   fprintf (dtl, UF4, l);
755
756   /* n[a+l] = font pathname string => area (directory) + font */
757   xferstring (a, dvi, dtl);
758   xferstring (l, dvi, dtl);
759
760   return (1 + n + 4 + 4 + 4 + 1 + 1 + a + l);
761 }
762 /* end fontdef */
763
764 COUNT
765 preamble
766 #ifdef STDC
767   (FILE * dvi,  FILE * dtl)
768 #else
769   (dvi,  dtl)
770   FILE * dvi;
771   FILE * dtl;
772 #endif
773 /* read preamble from dvi and write in dtl */
774 /* return number of DVI bytes interpreted into DTL */
775 {
776   U4 id, num, den, mag, k;
777
778   fprintf (dtl, "pre");
779
780   /* i[1] = DVI format identification */
781   fprintf (dtl, " ");
782   id = runsigned (1, dvi);
783   fprintf (dtl, UF4, id);
784
785   /* num[4] = numerator of DVI unit */
786   fprintf (dtl, " ");
787   num = runsigned (4, dvi);
788   fprintf (dtl, UF4, num);
789
790   /* den[4] = denominator of DVI unit */
791   fprintf (dtl, " ");
792   den = runsigned (4, dvi);
793   fprintf (dtl, UF4, den);
794
795   /* mag[4] = 1000 x magnification */
796   fprintf (dtl, " ");
797   mag = runsigned (4, dvi);
798   fprintf (dtl, UF4, mag);
799
800   /* k[1] = length of comment */
801   fprintf (dtl, " ");
802   k = runsigned (1, dvi);
803   fprintf (dtl, UF4, k);
804
805   /* x[k] = comment string */
806   xferstring (k, dvi, dtl);
807
808   return (1 + 1 + 4 + 4 + 4 + 1 + k);
809 }
810 /* end preamble */
811
812 COUNT
813 postamble
814 #ifdef STDC
815   (FILE * dvi,  FILE * dtl)
816 #else
817   (dvi,  dtl)
818   FILE * dvi;
819   FILE * dtl;
820 #endif
821 /* read postamble from dvi and write in dtl */
822 /* return number of bytes */
823 {
824   U4 p, num, den, mag, l, u, s, t;
825
826   fprintf (dtl, "post");
827
828   /* p[4] = pointer to final bop */
829   fprintf (dtl, " ");
830   p = runsigned (4, dvi);
831   fprintf (dtl, UF4, p);
832
833   /* num[4] = numerator of DVI unit */
834   fprintf (dtl, " ");
835   num = runsigned (4, dvi);
836   fprintf (dtl, UF4, num);
837
838   /* den[4] = denominator of DVI unit */
839   fprintf (dtl, " ");
840   den = runsigned (4, dvi);
841   fprintf (dtl, UF4, den);
842
843   /* mag[4] = 1000 x magnification */
844   fprintf (dtl, " ");
845   mag = runsigned (4, dvi);
846   fprintf (dtl, UF4, mag);
847
848   /* l[4] = height + depth of tallest page */
849   fprintf (dtl, " ");
850   l = runsigned (4, dvi);
851   fprintf (dtl, UF4, l);
852
853   /* u[4] = width of widest page */
854   fprintf (dtl, " ");
855   u = runsigned (4, dvi);
856   fprintf (dtl, UF4, u);
857
858   /* s[2] = maximum stack depth */
859   fprintf (dtl, " ");
860   s = runsigned (2, dvi);
861   fprintf (dtl, UF4, s);
862
863   /* t[2] = total number of pages (bop commands) */
864   fprintf (dtl, " ");
865   t = runsigned (2, dvi);
866   fprintf (dtl, UF4, t);
867
868 /*  return (29);  */
869   return (1 + 4 + 4 + 4 + 4 + 4 + 4 + 2 + 2);
870 }
871 /* end postamble */
872
873 COUNT
874 postpost
875 #ifdef STDC
876   (FILE * dvi,  FILE * dtl)
877 #else
878   (dvi,  dtl)
879   FILE * dvi;
880   FILE * dtl;
881 #endif
882 /* read post_post from dvi and write in dtl */
883 /* return number of bytes */
884 {
885   U4 q, id;
886   int b223;  /* hope this is 8-bit clean */
887   int n223;  /* number of "223" bytes in final padding */
888
889   fprintf (dtl, "post_post");
890
891   /* q[4] = pointer to post command */
892   fprintf (dtl, " ");
893   q = runsigned (4, dvi);
894   fprintf (dtl, UF4, q);
895
896   /* i[1] = DVI identification byte */
897   fprintf (dtl, " ");
898   id = runsigned (1, dvi);
899   fprintf (dtl, UF4, id);
900
901   /* final padding by "223" bytes */
902   /* hope this way of obtaining b223 is 8-bit clean */
903   for (n223 = 0; (b223 = fgetc (dvi)) == 223; n223++)
904   {
905     fprintf (dtl, " ");
906     fprintf (dtl, "%d", 223);
907   }
908   if (n223 < 4)
909   {
910     fprintf (stderr,
911       "%s:  bad post_post:  fewer than four \"223\" bytes.\n", program);
912     exit (1);
913   }
914   if (b223 != EOF)
915   {
916     fprintf (stderr,
917       "%s:  bad post_post:  doesn't end with a \"223\".\n", program);
918     exit (1);
919   }
920
921   return (1 + 4 + 1 + n223);
922 }
923 /* end postpost */
924
925 /* end of "dv2dt.c" */