home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / PasTeX / dvi2tty.lha / disdvi.c < prev    next >
C/C++ Source or Header  |  1990-12-18  |  16KB  |  593 lines

  1. /*****************************************************************************/
  2. /*                                                                           */
  3. /*   disdvi  ---  disassembles TeX dvi files.                                */
  4. /*                                                                           */
  5. /*                                                                           */
  6. /*   2.22 13dec90 M.J.E. Mol     Fixed bug in num(). Cleaned up code.        */
  7. /*   2.21 03may90 M.J.E. Mol     Created usage().                            */
  8. /*    2.2 02may90 M.J.E. Mol     Included port to VAX/VMS VAXC by            */
  9. /*                               Robert Schneider.                           */
  10. /*    2.1 19jan90 M.J.E. Mol     Maintain a list of fonts and                */
  11. /*                               show fontnames in font changes.             */
  12. /*                               Show character code when printing ligatures */
  13. /*    2.0 23jan89 M.J.E. Mol (c) 1989                                       */
  14. /*                                               marcel@duteca.et.tudelft.nl */
  15. /*                                                                           */
  16. /*****************************************************************************/
  17.  
  18.  
  19. char *disdvi = "@(#) disdvi.c  2.21 03/05/90 M.J.E. Mol (c) 1989, 1990";
  20.  
  21. /*
  22.  * Include files
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <ctype.h>
  27. #include "commands.h"
  28. #if defined(MSDOS)
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <fcntl.h>
  32. #endif
  33.  
  34.  
  35.  
  36. /*
  37.  * Constant definitions
  38.  */
  39.  
  40. #define LASTCHAR        127    /* max dvi character, above are commands    */
  41.  
  42. #define get1()           num(1)
  43. #define get2()           num(2)
  44. #define get3()           num(3)
  45. #define get4()           num(4)
  46. #define sget1()         snum(1)
  47. #define sget2()         snum(2)
  48. #define sget3()         snum(3)
  49. #define sget4()         snum(4)
  50.  
  51.  
  52.  
  53. /*
  54.  * Type definitions
  55.  */
  56.  
  57. typedef struct _font {
  58.     long    num;
  59.     struct _font * next;
  60.     char  * name;
  61. } font;
  62.  
  63.  
  64.  
  65. /*
  66.  * Variable declarations
  67.  */
  68.  
  69. font * fonts = NULL;
  70. FILE * dvifp;
  71. char * dvi_name;
  72. long   pc = 0;
  73.  
  74. char * progname;
  75.  
  76.  
  77. /*
  78.  * Funciton declarations
  79.  */
  80.  
  81. char *          malloc          ();
  82.  
  83. #if defined(VMS)
  84.                 main            ();
  85. #else
  86. void            main            ();
  87. #endif
  88. void            bop             ();
  89. void            preamble        ();
  90. void            postamble       ();
  91. void            postpostamble   ();
  92. void            fontdef         ();
  93. char *          fontname        ();
  94. void            special         ();
  95. void            printnonprint   ();
  96. unsigned long   num             ();
  97. long            snum            ();
  98. void            usage           ();
  99.  
  100.  
  101.  
  102.  
  103. /*
  104.  * MAIN --
  105.  */
  106.  
  107. #if defined(VMS)
  108.      main(argc, argv)
  109. #else
  110. void main(argc, argv)
  111. #endif
  112. int argc;
  113. char **argv;
  114. {
  115.     register int opcode;                /* dvi opcode                        */
  116.     register int i;
  117.     int fontnum;
  118.  
  119.     progname = *argv++;
  120.  
  121.     if (argc > 2) {
  122.         fprintf(stderr, "To many arguments\n");
  123.         usage();
  124.         exit(1);
  125.     }
  126.  
  127.     if (argc == 2) {
  128.         if (!strcmp(*argv, "-h")) {
  129.             usage();
  130.             exit(0);
  131.         }
  132.         if ((i = strlen(*argv)) == 0) {
  133.             fprintf(stderr, "Illegal empty filename\n");
  134.             usage();
  135.             exit(2);
  136.         }
  137.         if ((i >= 5) && (!strcmp(*argv+i-4, ".dvi")))
  138.             dvi_name = *argv;
  139.         else {
  140.             dvi_name = malloc((i+5) * sizeof(char));
  141.             strcpy(dvi_name, *argv);
  142.             strcat(dvi_name, ".dvi");
  143.         }
  144.         if ((dvifp = fopen(dvi_name, "r")) == NULL) {
  145.             perror(dvi_name);
  146.             exit(3);
  147.         }
  148.     }
  149.     else
  150.         dvifp = stdin;
  151.  
  152. #if defined(MSDOS)
  153.     setmode(fileno(dvifp), O_BINARY);
  154. #endif
  155.  
  156.     while ((opcode = (int) get1()) != EOF) {    /* process until end of file */
  157.         printf("%06ld: ", pc - 1);
  158.         if ((opcode <= LASTCHAR) && isprint(opcode)) {
  159.             printf("Char:     ");
  160.             while ((opcode <= LASTCHAR) && isprint(opcode)) {
  161.                 putchar(opcode);
  162.                 opcode = (int) get1();
  163.             }
  164.             putchar('\n');
  165.             printf("%06ld: ", pc - 1);
  166.         }
  167.  
  168.         if (opcode <= LASTCHAR) 
  169.             printnonprint(opcode);              /* it must be a non-printable */
  170.         else if ((opcode >= FONT_00) && (opcode <= FONT_63)) 
  171.             printf("FONT_%02d              /* %s */\n", opcode - FONT_00,
  172.                                     fontname(opcode - FONT_00));
  173.         else
  174.             switch (opcode) {
  175.                 case SET1     :
  176.                 case SET2     : 
  177.                 case SET3     :
  178.                 case SET4     : printf("SET%d:    %ld\n", opcode - SET1 + 1,
  179.                                                        num(opcode - SET1 + 1));
  180.                                 break;
  181.                 case SET_RULE : printf("SET_RULE: height: %ld\n", sget4());
  182.                                 printf("%06ld: ", pc);
  183.                                 printf("          length: %ld\n", sget4());
  184.                                 break;
  185.                 case PUT1     :
  186.                 case PUT2     :
  187.                 case PUT3     :
  188.                 case PUT4     : printf("PUT%d:     %ld\n", opcode - PUT1 + 1,
  189.                                                        num(opcode - PUT1 + 1));
  190.                                 break;
  191.                 case PUT_RULE : printf("PUT_RULE: height: %ld\n", sget4());
  192.                                 printf("%06ld: ", pc);
  193.                                 printf("          length: %ld\n", sget4());
  194.                                 break;
  195.                 case NOP      : printf("NOP\n");  break;
  196.                 case BOP      : bop();            break;
  197.                 case EOP      : printf("EOP\n");  break;
  198.                 case PUSH     : printf("PUSH\n"); break;
  199.                 case POP      : printf("POP\n");  break;
  200.                 case RIGHT1   :
  201.                 case RIGHT2   : 
  202.                 case RIGHT3   : 
  203.                 case RIGHT4   : printf("RIGHT%d:   %ld\n", opcode - RIGHT1 + 1,
  204.                                                      snum(opcode - RIGHT1 + 1));
  205.                                 break;
  206.                 case W0       : printf("W0\n");   break;
  207.                 case W1       : 
  208.                 case W2       :
  209.                 case W3       :
  210.                 case W4       : printf("W%d:       %ld\n", opcode - W0,
  211.                                                       snum(opcode - W0));
  212.                                 break;
  213.                 case X0       : printf("X0\n");   break;
  214.                 case X1       :
  215.                 case X2       :
  216.                 case X3       :
  217.                 case X4       : printf("X%d:       %ld\n", opcode - X0,
  218.                                                       snum(opcode - X0));
  219.                                 break;
  220.                 case DOWN1    : 
  221.                 case DOWN2    : 
  222.                 case DOWN3    :
  223.                 case DOWN4    : printf("DOWN%d:    %ld\n", opcode - DOWN1 + 1,
  224.                                                       snum(opcode - DOWN1 + 1));
  225.                                 break;
  226.                 case Y0       : printf("Y0\n");   break;
  227.                 case Y1       :
  228.                 case Y2       :
  229.                 case Y3       :
  230.                 case Y4       : printf("Y%d:       %ld\n", opcode - Y0,
  231.                                                       snum(opcode - Y0));
  232.                                 break;
  233.                 case Z0       : printf("Z0\n");   break;
  234.                 case Z1       :
  235.                 case Z2       :
  236.                 case Z3       : 
  237.                 case Z4       : printf("Z%d:       %ld\n", opcode - Z0,
  238.                                                       snum(opcode - Z0));
  239.                                 break;
  240.                 case FNT1     :
  241.                 case FNT2     :
  242.                 case FNT3     :
  243.                 case FNT4     : fontnum = num(opcode -FNT1 + 1);
  244.                                 printf("FNT%d:     %ld    /* %s */\n",
  245.                                        opcode - FNT1 + 1, fontnum,
  246.                                        fontname(fontnum));
  247.                                 break;
  248.                 case XXX1     : 
  249.                 case XXX2     : 
  250.                 case XXX3     :
  251.                 case XXX4     : special(opcode - XXX1 + 1);     break;
  252.                 case FNT_DEF1 :
  253.                 case FNT_DEF2 :
  254.                 case FNT_DEF3 :
  255.                 case FNT_DEF4 : fontdef(opcode - FNT_DEF1 + 1); break;
  256.                 case PRE      : preamble();                     break;
  257.                 case POST     : postamble();                    break;
  258.                 case POST_POST: postpostamble();                break;
  259.             }
  260.     }
  261.  
  262.     exit(0);
  263.  
  264. } /* main */
  265.  
  266.  
  267.  
  268. /*
  269.  * BOP -- Process beginning of page.
  270.  */
  271.  
  272. void bop()
  273. {
  274.     int i;
  275.  
  276.     printf("BOP       page number      : %ld", sget4());
  277.     for (i=9; i > 0; i--) {
  278.         if (i % 3 == 0)
  279.             printf("\n%06ld:         ", pc);
  280.         printf("  %6ld", sget4()); 
  281.     }
  282.     printf("\n%06ld: ", pc);
  283.     printf("          prev page offset : %06ld\n", sget4()); 
  284.  
  285.     return;
  286.  
  287. } /* bop */
  288.  
  289.  
  290.  
  291. /*
  292.  * POSTAMBLE -- Process post amble.
  293.  */
  294.  
  295. void postamble() 
  296. {
  297.  
  298.     printf("POST      last page offset : %06ld\n", sget4());
  299.     printf("%06ld: ", pc);
  300.     printf("          numerator        : %ld\n", get4());
  301.     printf("%06ld: ", pc);
  302.     printf("          denominator      : %ld\n", get4());
  303.     printf("%06ld: ", pc);
  304.     printf("          magnification    : %ld\n", get4());
  305.     printf("%06ld: ", pc);
  306.     printf("          max page height  : %ld\n", get4());
  307.     printf("%06ld: ", pc);
  308.     printf("          max page width   : %ld\n", get4());
  309.     printf("%06ld: ", pc);
  310.     printf("          stack size needed: %d\n", (int) get2());
  311.     printf("%06ld: ", pc);
  312.     printf("          number of pages  : %d\n", (int) get2());
  313.  
  314.     return;
  315.  
  316. } /* postamble */
  317.  
  318.  
  319.  
  320. /*
  321.  * PREAMBLE -- Process pre amble.
  322.  */
  323.  
  324. void preamble()
  325. {
  326.     register int i;
  327.  
  328.     printf("PRE       version          : %d\n", (int) get1());
  329.     printf("%06ld: ", pc);
  330.     printf("          numerator        : %ld\n", get4());
  331.     printf("%06ld: ", pc);
  332.     printf("          denominator      : %ld\n", get4());
  333.     printf("%06ld: ", pc);
  334.     printf("          magnification    : %ld\n", get4());
  335.     printf("%06ld: ", pc);
  336.     i = (int) get1();
  337.     printf("          job name (%3d)   :", i);
  338.     while (i-- > 0)
  339.         putchar((int) get1());
  340.     putchar('\n');
  341.  
  342.     return;
  343.  
  344. } /* preamble */
  345.  
  346.  
  347.  
  348. /*
  349.  * POSTPOSTAMBLE -- Process post post amble.
  350.  */
  351.  
  352. void postpostamble()
  353. {
  354.     register int i;
  355.  
  356.     printf("POSTPOST  postamble offset : %06ld\n", get4());
  357.     printf("%06ld: ", pc);
  358.     printf("          version          : %d\n", (int) get1());
  359.     while ((i = (int) get1()) == TRAILER) {
  360.         printf("%06d: ", pc - 1);
  361.         printf("TRAILER\n");
  362.     }
  363.     while (i != EOF) {
  364.         printf("%06ld: ", pc - 1);
  365.         printf("BAD DVI FILE END: 0x%02X\n", i);
  366.         i = (int) get1();
  367.     }
  368.  
  369.     return;
  370.  
  371. } /* postpostamble */
  372.  
  373.  
  374.  
  375. /*
  376.  * SPECIAL -- Process special opcode.
  377.  */
  378.  
  379. void special(x)
  380. register int x;
  381. {
  382.     register long len;
  383.  
  384.     len = num(x);
  385.     printf("XXX%d:     %ld bytes\n", x, len);
  386.     printf("%06ld: ", pc);
  387.     for (; len>0; len--)           /* a bit dangerous ... */
  388.         putchar((int) get1());     /*   can be non-printables */
  389.     putchar('\n');
  390.  
  391.     return;
  392.  
  393. } /* special */
  394.  
  395.  
  396.  
  397. /*
  398.  * FONTDEF -- Process a font definition.
  399.  */
  400.  
  401. void fontdef(x)
  402. register int x;
  403. {
  404.     register int i;
  405.     char * name;
  406.     font * fnt;
  407.     int namelen;
  408.     long fntnum;
  409.     int new = 0;
  410.  
  411.     fntnum = num(x);
  412.     printf("FNT_DEF%d: %ld\n", x, fntnum);
  413.     printf("%06ld: ", pc);           /* avoid side-effect on pc in get4() */
  414.     printf("          checksum         : %ld\n", get4());
  415.     printf("%06ld: ", pc);
  416.     printf("          scale            : %ld\n", get4());
  417.     printf("%06ld: ", pc);
  418.     printf("          design           : %ld\n", get4());
  419.     printf("%06ld: ", pc);
  420.     printf("          name             : ");
  421.     namelen = (int) get1() + (int) get1();
  422.     fnt = fonts;
  423.     while (fnt != NULL && fnt->num != fntnum)
  424.         fnt = fnt->next;
  425.     if (fnt == NULL) {
  426.         if ((fnt = (font *) malloc(sizeof(font))) == NULL) {
  427.             perror("fontdef");
  428.             exit(1);
  429.         }
  430.         fnt->num = fntnum;
  431.         new = 1;
  432.     }
  433.     else
  434.         free(fnt->name);    /* free old name */
  435.     if ((name = (char *) malloc(namelen * sizeof(char))) == NULL) {
  436.         perror("fontdef");
  437.         exit(1);
  438.     }
  439.     
  440.     for (i = 0; i < namelen; i++)
  441.         name[i] = get1();
  442.     fnt->name = name;
  443.     if (new) {
  444.         fnt->next = fonts;
  445.         fonts = fnt;
  446.     }
  447.  
  448.     printf("%s\n", name);
  449.  
  450.     return;
  451.  
  452. } /* fontdef */
  453.  
  454.  
  455.  
  456. /*
  457.  * FONTNAME -- Return font name.
  458.  */
  459.  
  460. char * fontname(fntnum)
  461. long fntnum;
  462. {
  463.     font * fnt;
  464.  
  465.     fnt = fonts;
  466.     while (fnt != NULL && fnt->num != fntnum)
  467.         fnt = fnt->next;
  468.     if (fnt != NULL)
  469.         return fnt->name;
  470.  
  471.     return "unknown fontname";
  472.    
  473. } /* fontname */
  474.  
  475.  
  476.  
  477. /*
  478.  * PRINTNONPRINT -- Translate non-printable characters.
  479.  */
  480.  
  481. void printnonprint(ch)
  482. register int ch;
  483. {
  484.  
  485.     printf("Char:     ");
  486.     switch (ch) {
  487.         case 11  :  printf("ff         /* ligature (non-printing) 0x%02X */",
  488.                            ch);
  489.                     break;
  490.         case 12  :  printf("fi         /* ligature (non-printing) 0x%02X */",
  491.                            ch);
  492.                     break;
  493.         case 13  :  printf("fl         /* ligature (non-printing) 0x%02X */",
  494.                            ch);
  495.                     break;
  496.         case 14  :  printf("ffi        /* ligature (non-printing) 0x%02X */",
  497.                            ch);
  498.                     break;
  499.         case 15  :  printf("ffl        /* ligature (non-printing) 0x%02X */",
  500.                            ch);
  501.                     break;
  502.         case 16  :  printf("i          /* (non-printing) 0x%02X */", ch);
  503.                     break;
  504.         case 17  :  printf("j          /* (non-printing) 0x%02X */", ch);
  505.                     break;
  506.         case 25  :  printf("ss         /* german (non-printing) 0x%02X */", ch);
  507.                     break;
  508.         case 26  :  printf("ae         /* scadinavian (non-printing) 0x%02X */",
  509.                            ch);
  510.                     break;
  511.         case 27  :  printf("oe         /* scadinavian (non-printing) 0x%02X */",
  512.                            ch);
  513.                     break;
  514.         case 28  :  printf("o          /* scadinavian (non-printing) 0x%02X */",
  515.                            ch);
  516.                     break;
  517.         case 29  :  printf("AE         /* scadinavian (non-printing) 0x%02X */",
  518.                            ch);
  519.                     break;
  520.         case 30  :  printf("OE         /* scadinavian (non-printing) 0x%02X */",
  521.                            ch);
  522.                     break;
  523.         case 31  :  printf("O          /* scadinavian (non-printing) 0x%02X */",
  524.                            ch);
  525.                     break;
  526.         default  :  printf("0x%02X", ch); break;
  527.     }
  528.     putchar('\n');
  529.  
  530.     return;
  531.  
  532. } /* printnonprint */
  533.  
  534.  
  535.  
  536. /*
  537.  * NUM --
  538.  */
  539.  
  540. unsigned long num(size)
  541. register int size;
  542. {
  543.     register int i;
  544.     register long x = 0;
  545.  
  546.     pc += size;
  547.     for (i = size; i > 0; i--)
  548.         x = (x << 8) + (unsigned) getc(dvifp);
  549.  
  550.     return x;
  551.  
  552. } /* num */
  553.  
  554.  
  555.  
  556. /*
  557.  * SNUM --
  558.  */
  559.  
  560. long snum(size)
  561. register int size;
  562. {
  563.     register int i;
  564.     register long x = 0;
  565.  
  566.     pc += size;
  567.     x = getc(dvifp);
  568.     if (x & 0x80)
  569.         x -= 0x100;
  570.     for (i = size - 1; i > 0; i--)
  571.         x = (x << 8) + (unsigned) getc(dvifp);
  572.  
  573.     return x;
  574.  
  575. } /* snum */
  576.  
  577.  
  578.  
  579. /*
  580.  * USAGE --
  581.  */
  582.  
  583. void usage()
  584. {
  585.  
  586.     fprintf(stderr, "\n%s\n\n", disdvi);
  587.     fprintf(stderr, "    disassembles TeX dvi files\n");
  588.     fprintf(stderr, "Usage: %s [-h | <dvi-file>[.dvi]]\n", progname);
  589.  
  590.     return;
  591.  
  592. } /* usage */
  593.