home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / text / tex / 13357 < prev    next >
Encoding:
Text File  |  1992-11-20  |  3.6 KB  |  110 lines

  1. Path: sparky!uunet!zaphod.mps.ohio-state.edu!news.acns.nwu.edu!network.ucsd.edu!mvb.saic.com!info-tex
  2. From: Libor Skarvada <libor@adelard.dcs.muni.cs>
  3. Newsgroups: comp.text.tex
  4. Subject: Re: how many pages ?
  5. Message-ID: <9211181717.AA08297@adelard.dcs.muni.cs>
  6. Date: Wed, 18 Nov 92 18:17:41 CET
  7. Organization: Info-Tex<==>Comp.Text.Tex Gateway
  8. X-Gateway-Source-Info: Mailing List
  9. Lines: 99
  10.  
  11. Barbara Beeton in her recent post is looking for an easy way how to
  12. determine the number of pages in a dvi file.  Here is a simple
  13. program that does the task.  I tested it on two plattforms (under
  14. SCO Unix System V with cc compiler and under MSDos with TurboC++).
  15. I hope it should work elsewhere too.  (But I am not sure whether
  16. my uses of strstr, fseek etc. are so much portable.)
  17. I appreciate all remarks ... yes, but Nov 21 thru Dec 6 I'll be out.
  18. --
  19. %=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%
  20. %  Libor Skarvada              Department of Computer Science           %
  21. %                              Masaryk University, Brno, Czechoslovakia %
  22. %  libor@dcs.muni.cs           phone:  +42-5-757000 (x369)              %
  23. %=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%
  24.  
  25.  -------- save as  npdvi.c  and build as a single one-file program --------
  26.  
  27. #include <stdio.h>
  28. #include <string.h>
  29.  
  30. #define Success  1
  31. #define BadPars -1   /* bad # of cmd line args */
  32. #define BadFile -2   /* nonexisting or ill-specified file */
  33. #define CorFile -3   /* dvi file has a strange format */
  34.  
  35. #define CMD_post_post 249
  36. #define CMD_fill      223
  37.  
  38. FILE *dvifile;
  39. unsigned long int getbigend(FILE *f,int len);
  40. unsigned int np(FILE *dvifile);
  41.  
  42. int main(int av,char **ac)
  43. { char filename[80];
  44.   unsigned int npages;
  45.  
  46.   if (av != 2) { fprintf(stderr,"npdvi -- usage:\nnpdvi <dvi-file>\n");
  47.                  return BadPars;
  48.                }
  49.  
  50.   strcpy(filename,*++ac);
  51.   dvifile = fopen(filename,"rb");
  52.   if (dvifile == NULL)
  53.     if (strstr(filename,".dvi") == NULL)
  54.       { strcat(filename,".dvi");   /* try again with filename.dvi */
  55.         dvifile = fopen(filename,"rb");
  56.       }
  57.   if (dvifile == NULL)
  58.     { perror("npdvi -- dvi file open problem");
  59.       return BadFile;
  60.     }
  61.  
  62.   npages = np(dvifile);
  63.  
  64.   if (npages == 0) { fprintf(stderr,"npdvi -- dvi file corrupted\n");
  65.                      return CorFile;
  66.                    }
  67.  
  68.   printf("The file %s has %d pages\n",filename,npages);
  69.   fclose(dvifile);
  70.   return Success;
  71. }
  72.  
  73. unsigned int np(FILE *dvifile)
  74. /*  returns number of bop cmds in dvifile
  75.  *  it is extracted from the postamble whose format is:
  76.  *    post lastbop[4] num[4] den[4] mag[4] maxh[4] maxw[4] stack[2] np[2]
  77.  *    <font definitions>
  78.  *    post_post q[4] id[1] 223s[>3]
  79.  *  where np is the total number of pages, q is pointer to post cmd
  80.  */
  81.  
  82. { unsigned b;
  83.   long unsigned postamble;
  84.  
  85.   fseek(dvifile,-1,SEEK_END); /* last byte */
  86.   do
  87.     { b = getc(dvifile);
  88.       fseek(dvifile,-2,SEEK_CUR);
  89.     }
  90.   while (b == CMD_fill);     /* the dvi file ends with a couple of 223's */
  91.   fseek(dvifile,-4,SEEK_CUR);   /* now we are at post_post cmd */
  92.   b = getc(dvifile);           /* and now just behind it */
  93.   if (b == CMD_post_post)
  94.     { postamble = getbigend(dvifile,4);        /* offset of post cmd */
  95.       fseek(dvifile,postamble+27,SEEK_SET);    /* now at the desired np */
  96.       return (int) getbigend(dvifile,2);
  97.     }
  98.     else return 0;
  99. }
  100.  
  101. unsigned long int getbigend(FILE *f,int len)
  102. /* reads len bytes from f and treats them as a number in BigEndian form */
  103. { unsigned long n;
  104.   int i;
  105.   for (i=0,n=0;i<len;i++)
  106.     n = 256*n + (long) getc(f);
  107.   return n;
  108. }
  109.  ------------------------  end of  npdvi.c  ------------------------
  110.