home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!zaphod.mps.ohio-state.edu!news.acns.nwu.edu!network.ucsd.edu!mvb.saic.com!info-tex
- From: Libor Skarvada <libor@adelard.dcs.muni.cs>
- Newsgroups: comp.text.tex
- Subject: Re: how many pages ?
- Message-ID: <9211181717.AA08297@adelard.dcs.muni.cs>
- Date: Wed, 18 Nov 92 18:17:41 CET
- Organization: Info-Tex<==>Comp.Text.Tex Gateway
- X-Gateway-Source-Info: Mailing List
- Lines: 99
-
- Barbara Beeton in her recent post is looking for an easy way how to
- determine the number of pages in a dvi file. Here is a simple
- program that does the task. I tested it on two plattforms (under
- SCO Unix System V with cc compiler and under MSDos with TurboC++).
- I hope it should work elsewhere too. (But I am not sure whether
- my uses of strstr, fseek etc. are so much portable.)
- I appreciate all remarks ... yes, but Nov 21 thru Dec 6 I'll be out.
- --
- %=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%
- % Libor Skarvada Department of Computer Science %
- % Masaryk University, Brno, Czechoslovakia %
- % libor@dcs.muni.cs phone: +42-5-757000 (x369) %
- %=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%=%
-
- -------- save as npdvi.c and build as a single one-file program --------
-
- #include <stdio.h>
- #include <string.h>
-
- #define Success 1
- #define BadPars -1 /* bad # of cmd line args */
- #define BadFile -2 /* nonexisting or ill-specified file */
- #define CorFile -3 /* dvi file has a strange format */
-
- #define CMD_post_post 249
- #define CMD_fill 223
-
- FILE *dvifile;
- unsigned long int getbigend(FILE *f,int len);
- unsigned int np(FILE *dvifile);
-
- int main(int av,char **ac)
- { char filename[80];
- unsigned int npages;
-
- if (av != 2) { fprintf(stderr,"npdvi -- usage:\nnpdvi <dvi-file>\n");
- return BadPars;
- }
-
- strcpy(filename,*++ac);
- dvifile = fopen(filename,"rb");
- if (dvifile == NULL)
- if (strstr(filename,".dvi") == NULL)
- { strcat(filename,".dvi"); /* try again with filename.dvi */
- dvifile = fopen(filename,"rb");
- }
- if (dvifile == NULL)
- { perror("npdvi -- dvi file open problem");
- return BadFile;
- }
-
- npages = np(dvifile);
-
- if (npages == 0) { fprintf(stderr,"npdvi -- dvi file corrupted\n");
- return CorFile;
- }
-
- printf("The file %s has %d pages\n",filename,npages);
- fclose(dvifile);
- return Success;
- }
-
- unsigned int np(FILE *dvifile)
- /* returns number of bop cmds in dvifile
- * it is extracted from the postamble whose format is:
- * post lastbop[4] num[4] den[4] mag[4] maxh[4] maxw[4] stack[2] np[2]
- * <font definitions>
- * post_post q[4] id[1] 223s[>3]
- * where np is the total number of pages, q is pointer to post cmd
- */
-
- { unsigned b;
- long unsigned postamble;
-
- fseek(dvifile,-1,SEEK_END); /* last byte */
- do
- { b = getc(dvifile);
- fseek(dvifile,-2,SEEK_CUR);
- }
- while (b == CMD_fill); /* the dvi file ends with a couple of 223's */
- fseek(dvifile,-4,SEEK_CUR); /* now we are at post_post cmd */
- b = getc(dvifile); /* and now just behind it */
- if (b == CMD_post_post)
- { postamble = getbigend(dvifile,4); /* offset of post cmd */
- fseek(dvifile,postamble+27,SEEK_SET); /* now at the desired np */
- return (int) getbigend(dvifile,2);
- }
- else return 0;
- }
-
- unsigned long int getbigend(FILE *f,int len)
- /* reads len bytes from f and treats them as a number in BigEndian form */
- { unsigned long n;
- int i;
- for (i=0,n=0;i<len;i++)
- n = 256*n + (long) getc(f);
- return n;
- }
- ------------------------ end of npdvi.c ------------------------
-