Back to index

tetex-bin  3.0
dvips.c
Go to the documentation of this file.
00001 /*
00002  *   This is the main routine.
00003  */
00004 #ifndef DEFRES
00005 #define DEFRES (600)
00006 #endif
00007 
00008 #include "dvips.h" /* The copyright notice there is included too! */
00009 #ifdef KPATHSEA
00010 #include <kpathsea/c-pathch.h>
00011 #include <kpathsea/proginit.h>
00012 #include <kpathsea/progname.h>
00013 #include <kpathsea/tex-hush.h>
00014 #include <kpathsea/tex-make.h>
00015 #include <kpathsea/lib.h>
00016 #ifdef strdup
00017 #undef strdup
00018 #endif
00019 #define strdup xstrdup
00020 #include "paths.h"
00021 #else /* ! KPATHSEA */
00022 #include <stdlib.h> /* for malloc, etc. */
00023 #if !defined(SYSV) && !defined(WIN32)
00024 extern char *strtok() ; /* some systems don't have this in strings.h */
00025 #endif
00026 #if defined(WIN32)
00027 #include <io.h>
00028 #include <fcntl.h>
00029 #include <string.h>
00030 #define O_BINARY _O_BINARY
00031 #endif
00032 #define DIR_SEP DIRSEP
00033 #endif /* KPATHSEA */
00034 #ifdef VMS
00035 #define GLOBAL globaldef
00036 #ifdef __GNUC__
00037 #include "climsgdef.h"      /* created by hand, extracted from STARLET.MLB */
00038                      /* and put in GNU_CC:[INCLUDE.LOCAL]           */
00039 #include "ctype.h"
00040 #include "descrip.h"
00041 #else
00042 #include climsgdef
00043 #include ctype
00044 #include descrip
00045 #endif
00046 #endif
00047 /*
00048  *   First we define some globals.
00049  */
00050 #ifdef VMS
00051     static char ofnme[252],infnme[252],pap[40],thh[20];
00052 #endif
00053 fontdesctype *fonthead ;      /* list of all fonts mentioned so far */
00054 fontdesctype *curfnt ;        /* the currently selected font */
00055 sectiontype *sections ;       /* sections to process document in */
00056 Boolean partialdownload = 1 ; /* turn on partial downloading */
00057 Boolean manualfeed ;          /* manual feed? */
00058 Boolean compressed ;          /* compressed? */
00059 Boolean downloadpspk ;        /* use PK for downloaded PS fonts? */
00060 Boolean safetyenclose ;
00061                           /* enclose in save/restore for stupid spoolers? */
00062 Boolean removecomments = 0 ;  /* remove comments from included PS? */
00063 Boolean nosmallchars ;        /* disable small char optimization for X4045? */
00064 Boolean cropmarks ;           /* add cropmarks? */
00065 Boolean abspage = 0 ;         /* are page numbers absolute? */
00066 Boolean tryepsf = 0 ;         /* should we try to make it espf? */
00067 Boolean secure = 0 ;          /* make safe for suid */
00068 int collatedcopies = 1 ;      /* how many collated copies? */
00069 int sectioncopies = 1 ;       /* how many times to repeat each section? */
00070 integer pagecopies = 1 ;          /* how many times to repeat each page? */
00071 shalfword linepos = 0 ;       /* where are we on the line being output? */
00072 integer maxpages ;            /* the maximum number of pages */
00073 Boolean notfirst, notlast ;   /* true if a first page was specified */
00074 Boolean evenpages, oddpages ; /* true if doing only even/only odd pages */
00075 Boolean pagelist ;            /* true if using page ranges */
00076 Boolean sendcontrolD ;        /* should we send a control D at end? */
00077 Boolean shiftlowchars ;       /* shift [0-32, 127] characters higher? */
00078 integer firstpage ;           /* the number of the first page if specified */
00079 integer lastpage ;
00080 integer firstseq ;
00081 integer lastseq ;
00082 integer hpapersize, vpapersize ; /* horizontal and vertical paper size */
00083 integer hoff, voff ;          /* horizontal and vertical offsets */
00084 integer maxsecsize = 0;       /* the maximum size of a section */
00085 integer firstboploc ;         /* where the first bop is */
00086 Boolean sepfiles ;            /* each section in its own file? */
00087 int numcopies ;               /* number of copies of each page to print */
00088 char *oname ;                 /* output file name */
00089 char *iname ;                 /* dvi file name */
00090 char *fulliname ;             /* same, with current working directory */
00091 char *strings ;               /* strings for program */
00092 char *nextstring, *maxstring ; /* string pointers */
00093 FILE *dvifile, *bitfile ;     /* dvi and output files */
00094 quarterword *curpos ;        /* current position in virtual character packet */
00095 quarterword *curlim ;         /* final byte in virtual character packet */
00096 fontmaptype *ffont ;          /* first font in current frame */
00097 real conv ;                   /* conversion ratio, pixels per DVI unit */
00098 real vconv ;                  /* conversion ratio, pixels per DVI unit */
00099 real alpha ;                  /* conversion ratio, DVI unit per TFM unit */
00100 double mag ;                  /* the magnification of this document */
00101 integer num, den ;            /* the numerator and denominator */
00102 int overridemag ;             /* substitute for mag value in DVI file? */
00103 int actualdpi = DEFRES ;      /* the actual resolution of the printer */
00104 int vactualdpi = DEFRES ;     /* the actual resolution of the printer */
00105 int maxdrift ;                /* max pixels away from true rounded position */
00106 int vmaxdrift ;               /* max pixels away from true rounded position */
00107 char *paperfmt ;              /* command-line paper format */
00108 int landscape = 0 ;           /* landscape mode */
00109 integer fontmem ;             /* memory remaining in printer */
00110 integer pagecount ;           /* page counter for the sections */
00111 integer pagenum ;             /* the page number we currently look at */
00112 long bytesleft ;              /* number of bytes left in raster */
00113 quarterword *raster ;         /* area for raster manipulations */
00114 integer hh, vv ;              /* horizontal and vertical pixel positions */
00115 Boolean noomega = 0 ;         /* Omega extensions are enabled */
00116 
00117 /*-----------------------------------------------------------------------*
00118  * The PATH definitions cannot be defined on the command line because so many
00119  * DEFINE's overflow the DCL buffer when using the GNU CC compiler.
00120  *-----------------------------------------------------------------------*/
00121 #if defined(VMS) && defined(__GNUC__)
00122 #include "vms_gcc_paths.h"
00123 #endif
00124 
00125 char *infont ;                /* is the file we are downloading a font? */
00126 #ifndef KPATHSEA
00127 #ifdef ATARIST
00128 #   define TFMPATH "."
00129 #   define PKPATH "."
00130 #   define VFPATH "."
00131 #   define FIGPATH "."
00132 #   define HEADERPATH "."
00133 #   define CONFIGPATH "."
00134 #endif
00135 char *tfmpath = TFMPATH ;     /* pointer to directories for tfm files */
00136 char *pkpath = PKPATH ;       /* pointer to directories for pk files */
00137 char *vfpath = VFPATH ;       /* pointer to directories for vf files */
00138 char *figpath = FIGPATH ;     /* pointer to directories for figure files */
00139 char *headerpath = HEADERPATH ; /* pointer to directories for header files */
00140 char *configpath = CONFIGPATH ; /* where to find config files */
00141 #ifndef PICTPATH
00142 #ifndef __THINK__
00143 #define PICTPATH "."
00144 #else
00145 #define PICTPATH ":"
00146 #endif
00147 #endif
00148 char *pictpath = PICTPATH ;   /* where IFF/etc. pictures are found */
00149 #ifdef SEARCH_SUBDIRECTORIES
00150 char *fontsubdirpath = FONTSUBDIRPATH ;
00151 #endif
00152 #endif /* ! KPATHSEA */
00153 #ifdef FONTLIB
00154 char *flipath = FLIPATH ;     /* pointer to directories for fli files */
00155 char *fliname = FLINAME ;     /* pointer to names of fli files */
00156 #endif
00157 integer swmem ;               /* font memory in the PostScript printer */
00158 int quiet ;                   /* should we only print errors to stderr? */
00159 int filter ;                  /* act as filter default output to stdout,
00160                                                default input to stdin? */
00161 int prettycolumn ;            /* the column we are at when running pretty */
00162 int gargc ;                   /* global argument count */
00163 char **gargv ;                /* global argument vector */
00164 int totalpages = 0 ;          /* total number of pages */
00165 Boolean reverse ;             /* are we going reverse? */
00166 Boolean usesPSfonts ;         /* do we use local PostScript fonts? */
00167 Boolean usesspecial ;         /* do we use \special? */
00168 Boolean headers_off ;         /* do we send headers or not? */
00169 Boolean usescolor ;           /* IBM: color - do we use colors? */
00170 char *headerfile ;            /* default header file */
00171 char *warningmsg ;            /* a message to write, if set in config file */
00172 Boolean multiplesects ;       /* more than one section? */
00173 Boolean disablecomments ;     /* should we suppress any EPSF comments? */
00174 char *printer ;               /* what printer to send this to? */
00175 char *mfmode ;                /* default MF mode */
00176 char *mflandmode ;            /* allow an optional landscape mode def */
00177 int mfmode_option;            /* set by -mode command-line option */
00178 int oname_option;             /* set by -o option */
00179 frametype frames[MAXFRAME] ;  /* stack for virtual fonts */
00180 integer pagecost;               /* memory used on the page being prescanned */
00181 int delchar;                    /* characters to delete from prescanned page */
00182 integer fsizetol;               /* max dvi units error for psfile font sizes */
00183 Boolean includesfonts;          /* are fonts used in included psfiles? */
00184 fontdesctype *fonthd[MAXFONTHD];/* list headers for included fonts of 1 name */
00185 int nextfonthd;                 /* next unused fonthd[] index */
00186 char xdig[256];                 /* table for reading hexadecimal digits */
00187 char banner[] = BANNER ;        /* our startup message */
00188 char banner2[] = BANNER2 ;      /* our second startup message */
00189 Boolean noenv = 0 ;             /* ignore PRINTER envir variable? */
00190 Boolean dopprescan = 0 ;        /* do we do a scan before the prescan? */
00191 extern int dontmakefont ;
00192 struct papsiz *papsizes ;       /* all available paper size */
00193 int headersready ;              /* ready to check headers? */
00194 #if defined(MSDOS) || defined(OS2) || defined(ATARIST)
00195 char *mfjobname = NULL;         /* name of mfjob file if given */
00196 FILE *mfjobfile = NULL;         /* mfjob file for font making instructions */
00197 #endif
00198 #ifdef DEBUG
00199 integer debug_flag = 0;
00200 #endif /* DEBUG */
00201 char queryline[256];                /* interactive query of options */
00202 int qargc;
00203 char *qargv[32];
00204 char queryoptions;
00205 /*
00206  *   This routine calls the following externals:
00207  */
00208 #include "protos.h"
00209 #ifdef HPS
00210 Boolean HPS_FLAG = 0 ;
00211 #endif
00212 extern int lastresortsizes[];
00213 extern char errbuf[];
00214 
00215 /* Declare the routine to get the current working directory.  */
00216 
00217 /* The getwd/getcwd stuff here is not portable, and I don't think it's
00218    worth it to include xgetcwd.d just so we can print the full pathname
00219    of the DVI file in the output. --karl */
00220 #define IGNORE_CWD
00221 
00222 #ifndef IGNORE_CWD
00223 #ifndef HAVE_GETCWD
00224 extern char *getwd (); /* said to be faster than getcwd (SunOS man page) */
00225 #define getcwd(b, len)  getwd(b) /* used here only when b nonnull */
00226 #else
00227 #ifdef ANSI
00228 extern char *getcwd (char *, int);
00229 #else
00230 extern char *getcwd ();
00231 #endif /* not ANSI */
00232 #endif /* not HAVE_GETWD */
00233 #if defined(SYSV) || defined(VMS) || (defined(MSDOS) && !defined(__DJGPP__)) || defined(OS2) || defined(ATARIST)
00234 #define MAXPATHLEN (256)
00235 #else
00236 #include <sys/param.h>          /* for MAXPATHLEN */
00237 #endif
00238 #endif /* not IGNORE_CWD */
00239 
00240 static char *helparr[] = {
00241 #ifndef VMCMS
00242 "Usage: dvips [OPTION]... FILENAME[.dvi]",
00243 #else
00244 "    VM/CMS Usage:",
00245 "           dvips fname [ftype [fmode]] [options]",
00246 "or",
00247 "           dvips fname[.ftype[.fmode]] [options]",
00248 #endif
00249 "a*  Conserve memory, not time      A   Print only odd (TeX) pages      ",
00250 "b # Page copies, for posters e.g.  B   Print only even (TeX) pages     ",
00251 "c # Uncollated copies              C # Collated copies                 ",
00252 "d # Debugging                      D # Resolution                      ",
00253 "e # Maxdrift value                 E*  Try to create EPSF              ",
00254 "f*  Run as filter                  F*  Send control-D at end           ",
00255 #ifdef SHIFTLOWCHARS
00256 "                                   G*  Shift low chars to higher pos.  ",
00257 #endif
00258 "h f Add header file                                                    ",
00259 "i*  Separate file per section                                          ",
00260 "j*  Download fonts partially                                           ",
00261 "k*  Print crop marks               K*  Pull comments from inclusions   ",
00262 "l # Last page                                                          ",
00263 "m*  Manual feed                    M*  Don't make fonts                ",
00264 "mode s Metafont device name                                            ",
00265 "n # Maximum number of pages        N*  No structured comments          ",
00266 "noomega  Disable Omega extensions                                      ",
00267 "o f Output file                    O c Set/change paper offset         ",
00268 #if defined(MSDOS) || defined(OS2)
00269 "p # First page                     P s Load $s.cfg                     ",
00270 #else
00271 "p # First page                     P s Load config.$s                  ",
00272 #endif
00273 "pp l Print only pages listed                                           ",
00274 "q*  Run quietly                                                        ",
00275 "r*  Reverse order of pages         R*  Run securely                    ",
00276 "s*  Enclose output in save/restore S # Max section size in pages       ",
00277 "t s Paper format                   T c Specify desired page size       ",  
00278 "u s PS mapfile                     U*  Disable string param trick      ",
00279 "v   Print version number and quit  V*  Send downloadable PS fonts as PK",
00280 "x # Override dvi magnification     X # Horizontal resolution           ",
00281 "y # Multiply by dvi magnification  Y # Vertical resolution             ",  
00282 #ifdef HPS
00283 "z*  Hyper PS                       Z*  Compress bitmap fonts           ",
00284 #else
00285 "                                   Z*  Compress bitmap fonts           ",
00286 #endif
00287 /* "-   Interactive query of options", */
00288 "    # = number   f = file   s = string  * = suffix, `0' to turn off    ",
00289 "    c = comma-separated dimension pair (e.g., 3.2in,-32.1cm)           ",
00290 "    l = comma-separated list of page ranges (e.g., 1-4,7-9)            ", 0} ;
00291 
00292 void
00293 help P1C(int, status)
00294 {
00295    char **p;
00296    FILE *f = status == 0 ? stdout : stderr;
00297 #ifdef KPATHSEA
00298    extern KPSEDLL char *kpse_bug_address;
00299 #endif   
00300    for (p=helparr; *p; p++)
00301       fprintf (f, "%s\n", *p);
00302 
00303    putc ('\n', f);
00304 #ifdef KPATHSEA
00305    fputs (kpse_bug_address, f);
00306 #endif
00307 }
00308 /*
00309  *   This error routine prints an error message; if the first
00310  *   character is !, it aborts the job.
00311  */
00312 
00313 static char *progname ;
00314 
00315 void
00316 error_with_perror P2C(char *, s, char *, fname)
00317 {
00318    if (prettycolumn > 0)
00319         fprintf(stderr,"\n");
00320    prettycolumn = 0;
00321    (void)fprintf(stderr, "%s: %s", progname, s) ;
00322    if (fname) {
00323      putc (' ', stderr);
00324      perror (fname);
00325    } else {
00326      putc ('\n', stderr);
00327    }
00328    
00329    if (*s=='!') {
00330       if (bitfile != NULL) {
00331          cleanprinter() ;
00332       }
00333       exit(1) ; /* fatal */
00334    }
00335 }
00336 
00337 /*
00338  *   This error routine prints an error message; if the first
00339  *   character is !, it aborts the job.
00340  */
00341 void
00342 error P1C(char *, s)
00343 {
00344    error_with_perror (s, NULL);
00345 }
00346 
00347 #ifndef KPATHSEA
00348 char *concat P2C(char *, s1, char *, s2)
00349 { 
00350   char *s = malloc(strlen(s1)+strlen(s2)+1);
00351   if (s == NULL) {
00352     fprintf(stderr, "Malloc failed to give %d bytes.\nAborting\n",
00353            strlen(s1)+strlen(s2)+1);
00354     exit(1);
00355   }
00356   strcpy(s, s1);
00357   strcat(s, s2);
00358 }
00359 #endif
00360 
00361 /* Report a warning if both checksums are nonzero, they don't match, and
00362    the user hasn't turned it off.  */
00363 
00364 void
00365 check_checksum P3C(unsigned, c1, unsigned, c2, const char *, name)
00366 {
00367   if (c1 && c2 && c1 != c2 
00368 #ifdef KPATHSEA
00369       && !kpse_tex_hush ("checksum")
00370 #endif
00371       ) {
00372      sprintf (errbuf, "Checksum mismatch in %s", name);
00373      error (errbuf);
00374    }
00375 }
00376 
00377 /*
00378  *   This is our malloc that checks the results.  We debug the
00379  *   allocations but not the frees, since memory fragmentation
00380  *   might be such that we can never use the free'd memory and
00381  *   it's wise to be conservative.  The only real place we free
00382  *   is when repacking *huge* characters anyway.
00383  */
00384 #ifdef DEBUG
00385 static integer totalalloc = 0 ;
00386 #endif
00387 char *mymalloc P1C(integer, n)
00388 {
00389    char *p ;
00390 
00391 #ifdef SMALLMALLOC
00392    if (n > 65500L)
00393       error("! can't allocate more than 64K!") ;
00394 #endif
00395    if (n <= 0) /* catch strange 0 mallocs in flib.c without breaking code */
00396       n = 1 ;
00397 #ifdef DEBUG
00398    totalalloc += n ;
00399    if (dd(D_MEM)) {
00400 #ifdef SHORTINT
00401       fprintf(stderr, "Alloc %ld\n", n) ;
00402 #else
00403       fprintf(stderr, "Alloc %d\n", n) ;
00404 #endif
00405    }
00406 #endif
00407    p = (char *) malloc(n) ;
00408    if (p == NULL)
00409       error("! no memory") ;
00410    return p ;
00411 }
00412 void
00413 morestrings P1H(void) {
00414    strings = mymalloc((integer)STRINGSIZE) ;
00415    nextstring = strings ;
00416    maxstring = strings + STRINGSIZE - 200 ;
00417    *nextstring++ = 0 ;
00418 }
00419 void
00420 checkstrings P1H(void) {
00421    if (nextstring - strings > STRINGSIZE / 2)
00422       morestrings() ;
00423 }
00424 /*
00425  *   Initialize sets up all the globals and data structures.
00426  */
00427 void
00428 initialize P1H(void)
00429 {
00430    int i;
00431    char *s;
00432 
00433    nextfonthd = 0;
00434    for (i=0; i<256; i++)
00435       xdig[i] = 0;
00436    i = 0;
00437    for (s="0123456789ABCDEF"; *s!=0; s++)
00438       xdig[(int)*s] = i++;
00439    i = 10;
00440    for (s="abcdef"; *s!=0; s++)
00441       xdig[(int)*s] = i++;
00442    morestrings() ;
00443    maxpages = 100000 ;
00444    numcopies = 1 ;
00445    iname = fulliname = strings ;
00446    bitfile = NULL ;
00447    bytesleft = 0 ;
00448    swmem = SWMEM ;
00449    oname = OUTPATH ;
00450    sendcontrolD = 0 ;
00451    shiftlowchars = 0 ;
00452    multiplesects = 0 ;
00453    disablecomments = 0 ;
00454    maxdrift = -1 ;
00455    vmaxdrift = -1 ;
00456    dontmakefont = !MAKE_TEX_PK_BY_DEFAULT;
00457 }
00458 /*
00459  *   This routine copies a string into the string `pool', safely.
00460  */
00461 char *
00462 newstring P1C(char *, s)
00463 {
00464    int l ;
00465 
00466    if (s == NULL)
00467       return(NULL) ;
00468    l = strlen(s) ;
00469    if (nextstring + l >= maxstring)
00470       morestrings() ;
00471    if (nextstring + l >= maxstring)
00472       error("! out of string space") ;
00473    (void)strcpy(nextstring, s) ;
00474    s = nextstring ;
00475    nextstring += l + 1 ;
00476    return(s) ;
00477 }
00478 void newoutname P1H(void) {
00479    static int seq = 0 ;
00480    static char *seqptr = 0 ;
00481    char *p ;
00482 
00483    if (oname == 0 || *oname == 0)
00484       error("! need an output file name to specify separate files") ;
00485    if (*oname != '!' && *oname != '|') {
00486       if (seqptr == 0) {
00487          oname = newstring(oname) ;
00488          seqptr = 0 ;
00489          for (p = oname; *p; p++)    /* find last dot after last slash */
00490             if (*p == '.')
00491                seqptr = p + 1 ;
00492             else if (*p == '/')
00493                seqptr = 0 ;
00494 #ifdef DOSISH
00495             else if (*p == '\\')
00496                seqptr = 0 ;
00497 #endif
00498          if (seqptr == 0)
00499             seqptr = p ;
00500          nextstring += 5 ; /* make room for the number, up to five digits */
00501       }
00502       sprintf(seqptr, "%03d", ++seq) ;
00503    }
00504 }
00505 /*
00506  *   This routine reverses a list, where a list is defined to be any
00507  *   structure whose first element is a pointer to another such structure.
00508  */
00509 VOID *revlist P1C(VOID *, p)
00510 {
00511    struct list {
00512       struct list *next ;
00513    } *pp = (struct list *)p, *qq = 0, *tt ;
00514 
00515    while (pp) {
00516       tt = pp->next ;
00517       pp->next = qq ;
00518       qq = pp ;
00519       pp = tt ;
00520    }
00521    return (VOID *)qq ;
00522 }
00523 /* this asks for a new set of arguments from the command line */
00524 void
00525 queryargs P1H(void)
00526 {
00527    fputs("Options: ",stdout);
00528    fgets(queryline,256,stdin);
00529    qargc=1;
00530    if ( (qargv[1] = strtok(queryline," \n")) != (char *)NULL ) {
00531       qargc=2;
00532       while ( ((qargv[qargc] = strtok((char *)NULL," \n")) != (char *)NULL)
00533             && (qargc < 31) )
00534          qargc++;
00535    }
00536    qargv[qargc] = (char *)NULL;
00537 }
00538  
00539 /*
00540  *   Finally, our main routine.
00541  */
00542 extern void handlepapersize() ;
00543 #ifdef VMS
00544 main P1H(void)
00545 #else
00546 int
00547 main P2C(int, argc, char **, argv)
00548 #endif
00549 {
00550    int i, lastext = -1 ;
00551 #ifdef MVSXA
00552    int firstext = -1 ;
00553 #endif
00554    register sectiontype *sects ;
00555 
00556 #ifdef KPATHSEA
00557    kpse_set_program_name (argv[0], "dvips");
00558    kpse_set_program_enabled (kpse_pk_format, MAKE_TEX_PK_BY_DEFAULT, kpse_src_compile);
00559 #endif
00560    
00561 #ifdef __THINK__
00562    argc = dcommand(&argv) ; /* do I/O stream redirection */
00563 #endif
00564 #ifdef VMS           /* Grab the command-line buffer */
00565    short len_arg;
00566    $DESCRIPTOR( verb_dsc, "DVIPS ");      /* assume the verb is always DVIPS */
00567    struct dsc$descriptor_d temp_dsc = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_D, 0};
00568 
00569    progname = &thh[0] ;
00570    strcpy(progname,"DVIPS%ERROR");
00571 
00572    lib$get_foreign( &temp_dsc, 0, &len_arg, 0);  /* Get the command line */
00573    str$prefix(&temp_dsc, &verb_dsc);             /* prepend the VERB     */
00574    len_arg += verb_dsc.dsc$w_length;             /* update the length    */
00575    temp_dsc.dsc$a_pointer[len_arg] = '\0';       /* terminate the string */
00576    gargv = &temp_dsc.dsc$a_pointer;              /* point to the buffer  */
00577    gargc = 1 ;                                   /* only one big argv    */
00578 #else
00579    progname = argv[0] ;
00580    gargv = argv ;
00581    gargc = argc ;
00582 /* we sneak a look at the first arg in case it's debugging */
00583 #ifdef DEBUG
00584    if (argc > 1 && strncmp(argv[1], "-d", 2)==0) {
00585       if (argv[1][2]==0 && argc > 2) {
00586          if (sscanf(argv[2], "%d", &debug_flag)==0)
00587             debug_flag = 0 ;
00588       } else {
00589          if (sscanf(argv[1]+2, "%d", &debug_flag)==0)
00590             debug_flag = 0 ;
00591       }
00592    }
00593 #ifdef KPATHSEA
00594    if (dd(D_FILES)) KPSE_DEBUG_SET (KPSE_DEBUG_FOPEN);
00595    if (dd(D_PATHS)) KPSE_DEBUG_SET (KPSE_DEBUG_PATHS);
00596    if (dd(D_STAT)) KPSE_DEBUG_SET (KPSE_DEBUG_STAT);
00597    if (dd(D_HASH)) KPSE_DEBUG_SET (KPSE_DEBUG_HASH);
00598    if (dd(D_EXPAND)) KPSE_DEBUG_SET (KPSE_DEBUG_EXPAND);
00599    if (dd(D_SEARCH)) KPSE_DEBUG_SET (KPSE_DEBUG_SEARCH);
00600 #endif /* KPATHSEA */
00601 #endif /* DEBUG */
00602 #ifdef KPATHSEA
00603    if (argc > 1) {
00604       if (strcmp (argv[1], "--help") == 0) {
00605         help (0);
00606         exit (0);
00607       } else if (strcmp (argv[1], "--version") == 0) {
00608         extern KPSEDLL char *kpathsea_version_string;
00609         puts ("dvips(k) 5.95a");
00610         puts (kpathsea_version_string);
00611         puts ("Copyright (C) 2005 Radical Eye Software.\n\
00612 There is NO warranty.  You may redistribute this software\n\
00613 under the terms of the GNU General Public License\n\
00614 and the Dvips copyright.\n\
00615 For more information about these matters, see the files\n\
00616 named COPYING and dvips.h.\n\
00617 Primary author of Dvips: T. Rokicki; -k maintainer: T. Kacvinsky/ S. Rahtz.");
00618         exit (0);
00619       }
00620       if (argc == 2 && strncmp(argv[1], "-?", 2) == 0) {
00621          printf("%s %s\n", banner, banner2) ;
00622          help(0);
00623          exit(0);
00624       }
00625       if (argc == 2 && strncmp(argv[1], "-v", 2) == 0) {
00626          printf("%s %s\n", banner, banner2) ;
00627          exit(0);
00628       }
00629    }
00630 #endif
00631 #endif
00632    initialize() ;
00633    checkenv(0) ;
00634    getdefaults(CONFIGFILE) ;
00635    getdefaults((char *)0) ;
00636 /*
00637  *   This next whole big section of code is straightforward; we just scan
00638  *   the options.  An argument can either immediately follow its option letter
00639  *   or be separated by spaces.  Any argument not preceded by '-' and an
00640  *   option letter is considered a file name; the program complains if more
00641  *   than one file name is given, and uses stdin if none is given.
00642  */
00643 #ifdef VMS
00644    vmscli P1H(void);
00645    papsizes = (struct papsiz *)revlist((void *)papsizes) ; /* Added by PWD 21-Mar-1997 */
00646 #else
00647    queryoptions = 0;
00648    do
00649    {
00650       for (i=1; i<argc; i++) {
00651          if (*argv[i]=='-') {
00652             char *p=argv[i]+2 ;
00653             char c=argv[i][1] ;
00654             switch (c) {
00655 case '-':
00656                queryoptions = 1;
00657                break;
00658 case 'a':
00659                dopprescan = (*p != '0') ;
00660                break ;
00661 case 'b':
00662                if (*p == 0 && argv[i+1])
00663                   p = argv[++i] ;
00664                if (sscanf(p, "%d", &pagecopies)==0)
00665                   error("! Bad number of page copies option (-b).") ;
00666                if (pagecopies < 1 || pagecopies > 1000)
00667                   error("! can only print one to a thousand page copies") ;
00668                break ;
00669 case 'c' :
00670                if (*p == 0 && argv[i+1])
00671                   p = argv[++i] ;
00672                if (sscanf(p, "%d", &numcopies)==0)
00673                   error("! Bad number of copies option (-c).") ;
00674                break ;
00675 case 'd' :
00676 #ifdef DEBUG
00677                {
00678                   int old_debug = debug_flag ;
00679                   static int warned_already = 0 ;
00680 
00681                   if (*p == 0 && argv[i+1])
00682                      p = argv[++i];
00683                   if (sscanf(p, "%d", &debug_flag)==0)
00684                      error("! Bad debug option (-d).");
00685                   if (debug_flag != old_debug && warned_already++ == 0) {
00686                      fprintf(stderr,
00687   "I found a debug option that was not the first argument to the dvips\n") ;
00688                      fprintf(stderr,
00689   "command.  Some debugging output may have been lost because of this.\n") ;
00690                   }
00691                   break;
00692                }
00693 #else
00694                error("not compiled in debug mode") ;
00695                break ;
00696 #endif /* DEBUG */
00697 case 'e' :
00698                if (*p == 0 && argv[i+1])
00699                   p = argv[++i] ;
00700                if (sscanf(p, "%d", &maxdrift)==0 || maxdrift<0)
00701                   error("! Bad maxdrift option (-e).") ;
00702                vmaxdrift = maxdrift;
00703                break ;
00704 case 'f' :
00705                filter = (*p != '0') ;
00706                if (filter)
00707                   oname = "" ;
00708                noenv = 1 ;
00709                sendcontrolD = 0 ;
00710                break ;
00711 case 'u' :
00712                {
00713                   extern char *psmapfile;
00714                   char PSname[300] ;               
00715                   if (*p == 0 && argv[i+1])
00716                      p = argv[++i] ;
00717                   strcpy(PSname, p) ;
00718                   if (!strchr(PSname, '.'))        
00719                      strcat(PSname, ".map") ;     /* default extension */
00720                   if (PSname[0] == '+')
00721                      getpsinfo(PSname+1) ;
00722                   else 
00723                      psmapfile = strdup(PSname) ; /* a cute small memory leak (just as in 'p' option handling in resident.c) */
00724                }
00725                break ;
00726 case 'h' : case 'H' :
00727                if (*p == 0 && argv[i+1])
00728                   p = argv[++i] ;
00729                if (strcmp(p, "-") == 0)
00730                   headers_off = 1 ;
00731                else
00732                   (void)add_header(p) ;
00733                break ;
00734 case 'i':
00735                sepfiles = (*p != '0') ;
00736                if (sepfiles && maxsecsize == 0) {
00737                  maxsecsize = 1; /* default section size to one page/file */
00738                }
00739                break ;
00740 case 'j':
00741                partialdownload = (*p != '0') ;
00742                break ;
00743 case 'k':
00744                cropmarks = (*p != '0') ;
00745                break ;
00746 case 'R':
00747                secure = (*p != '0') ;
00748                break ;
00749 case 'S':
00750                if (*p == 0 && argv[i+1])
00751                   p = argv[++i] ;
00752                if (sscanf(p, "%d", &maxsecsize)==0)
00753                   error("! Bad section size arg (-S).") ;
00754                break ;
00755 case 'm' :
00756                if (STREQ (p, "ode") && argv[i+1]) {
00757                  mfmode = argv[++i];
00758                  mfmode_option = 1;
00759                } else
00760                  manualfeed = (*p != '0') ;
00761                break ;
00762 case 'n' :
00763                if (STREQ (p, "oomega")) {
00764                  noomega = 1 ;
00765                } else {
00766                if (*p == 0 && argv[i+1])
00767                   p = argv[++i] ;
00768 #ifdef SHORTINT
00769                if (sscanf(p, "%ld", &maxpages)==0)
00770 #else        /* ~SHORTINT */
00771                if (sscanf(p, "%d", &maxpages)==0)
00772 #endif        /* ~SHORTINT */
00773                   error("! Bad number of pages option (-n).") ;
00774                }
00775                break ;
00776 case 'o' :
00777                if (*p == 0 && argv[i+1] && 
00778                    (STREQ (argv[i+1], "-") || argv[i+1][0] != '-'))
00779                   p = argv[++i] ;
00780                oname_option = 1;
00781                oname = p ;
00782                noenv = 1 ;
00783                sendcontrolD = 0 ;
00784 #if defined(MSDOS) || defined(OS2)
00785                 if (*oname && oname[strlen(oname)-1] == ':')
00786                     oname[strlen(oname)-1] = 0;     /* strip ':' off */
00787 #endif
00788                break ;
00789 case 'O' :
00790                if (*p == 0 && argv[i+1])
00791                   p = argv[++i] ;
00792                handlepapersize(p, &hoff, &voff) ;
00793                break ;
00794 case 'T' :
00795                if (*p == 0 && argv[i+1])
00796                   p = argv[++i] ;
00797                handlepapersize(p, &hpapersize, &vpapersize) ;
00798                if (landscape) {
00799                   error(
00800               "both landscape and papersize specified; ignoring landscape") ;
00801                   landscape = 0 ;
00802                }
00803                break ;
00804 case 'p' :
00805 #if defined(MSDOS) || defined(OS2) || defined(ATARIST)
00806                /* check for emTeX job file (-pj=filename) */
00807                if (*p == 'j') {
00808                  p++;
00809                  if (*p == '=' || *p == ':')
00810                    p++;
00811                  mfjobname = newstring(p);
00812                  break;
00813                }
00814                /* must be page number instead */
00815 #endif
00816                if (*p == 'p') {  /* a -pp specifier for a page list? */
00817                   p++ ;
00818                   if (*p == 0 && argv[i+1])
00819                      p = argv[++i] ;
00820                   if (ParsePages(p))
00821                      error("! Bad page list specifier (-pp).") ;
00822                   pagelist = 1 ;
00823                   break ;
00824                }
00825                if (*p == 0 && argv[i+1])
00826                   p = argv[++i] ;
00827                if (*p == '=') {
00828                   abspage = 1 ;
00829                   p++ ;
00830                }
00831 #ifdef SHORTINT
00832                switch(sscanf(p, "%ld.%ld", &firstpage, &firstseq)) {
00833 #else        /* ~SHORTINT */
00834                switch(sscanf(p, "%d.%d", &firstpage, &firstseq)) {
00835 #endif        /* ~SHORTINT */
00836 case 1:           firstseq = 0 ;
00837 case 2:           break ;
00838 default:
00839 #ifdef KPATHSEA
00840                   error(concat3 ("! Bad first page option (-p ", p, ").")) ;
00841 #else
00842                   error("! Bad first page option (-p).") ;
00843 #endif
00844                }
00845                notfirst = 1 ;
00846                break ;
00847 case 'l':
00848                if (*p == 0 && argv[i+1])
00849                   p = argv[++i] ;
00850                if (*p == '=') {
00851                   abspage = 1 ;
00852                   p++ ;
00853                }
00854 #ifdef SHORTINT
00855                switch(sscanf(p, "%ld.%ld", &lastpage, &lastseq)) {
00856 #else        /* ~SHORTINT */
00857                switch(sscanf(p, "%d.%d", &lastpage, &lastseq)) {
00858 #endif        /* ~SHORTINT */
00859 case 1:           lastseq = 0 ;
00860 case 2:           break ;
00861 default:
00862 #ifdef KPATHSEA
00863                   error(concat3 ("! Bad last page option (-l ", p, ").")) ;
00864 #else
00865                   error("! Bad last page option (-l).") ;
00866 #endif
00867                }
00868                notlast = 1 ;
00869                break ;
00870 case 'A':
00871                oddpages = 1 ;
00872                break ;
00873 case 'B':
00874                evenpages = 1 ;
00875                break ;
00876 case 'q' : case 'Q' :
00877                quiet = (*p != '0') ;
00878                break ;
00879 case 'r' :
00880                reverse = (*p != '0') ;
00881                break ;
00882 case 't' :
00883                if (*p == 0 && argv[i+1])
00884                   p = argv[++i] ;
00885                if (strcmp(p, "landscape") == 0) {
00886                   if (hpapersize || vpapersize)
00887                      error(
00888              "both landscape and papersize specified; ignoring landscape") ;
00889                   else
00890                      landscape = 1 ;
00891                } else
00892                   paperfmt = p ;
00893                break ;
00894 case 'v':
00895                 printf ("%s %s\n", banner, banner2);
00896                 exit (0);
00897                 break;
00898 case 'x' : case 'y' :
00899                if (*p == 0 && argv[i+1])
00900                   p = argv[++i] ;
00901                if (sscanf(p, "%lg", &mag)==0 || mag < 1 ||
00902                           mag > 1000000)
00903                   error("! Bad magnification parameter (-x or -y).") ;
00904                overridemag = (c == 'x' ? 1 : -1) ;
00905                break ;
00906 case 'C' :
00907                if (*p == 0 && argv[i+1])
00908                   p = argv[++i] ;
00909                if (sscanf(p, "%d", &collatedcopies)==0)
00910                   error("! Bad number of collated copies option (-C).") ;
00911                break ;
00912 case 'D' :
00913                if (*p == 0 && argv[i+1])
00914                   p = argv[++i] ;
00915                if (sscanf(p, "%d", &actualdpi)==0 || actualdpi < 10 ||
00916                           actualdpi > 10000)
00917                   error("! Bad dpi parameter (-D).") ;
00918                vactualdpi = actualdpi;
00919                /* If we had the mode from config.ps, don't use it.
00920                   If they specified one with -mode, keep it.  */
00921                if (!mfmode_option)
00922                  mfmode = NULL;
00923                break ;
00924 case 'E' :
00925                tryepsf = (*p != '0') ;
00926                removecomments = disablecomments = 0;
00927                if (tryepsf && maxsecsize == 0)
00928                   maxsecsize = 1 ;
00929                break ;
00930 case 'K' :
00931                removecomments = (*p != '0') ;
00932                break ;
00933 case 'U' :
00934                nosmallchars = (*p != '0') ;
00935                break ;
00936 case 'X' :
00937                if (*p == 0 && argv[i+1])
00938                   p = argv[++i] ;
00939                if (sscanf(p, "%d", &actualdpi)==0 || actualdpi < 10 ||
00940                           actualdpi > 10000)
00941                   error("! Bad dpi parameter (-D).") ;
00942                break ;
00943 case 'Y' :
00944                if (*p == 0 && argv[i+1])
00945                   p = argv[++i] ;
00946                if (sscanf(p, "%d", &vactualdpi)==0 || vactualdpi < 10 ||
00947                           vactualdpi > 10000)
00948                   error("! Bad dpi parameter (-D).") ;
00949                vactualdpi = vactualdpi;
00950                break ;
00951 case 'F' :
00952                sendcontrolD = (*p != '0') ;
00953                break ;
00954 case 'G' :
00955                shiftlowchars = (*p != '0');
00956               break;
00957 case 'M':
00958                dontmakefont = (*p != '0') ;
00959 #ifdef KPATHSEA
00960                kpse_set_program_enabled (kpse_pk_format, !dontmakefont,
00961                                          kpse_src_cmdline);
00962 #endif
00963                break ;
00964 case 'N' :
00965                disablecomments = (*p != '0') ;
00966                break ;
00967 case 'P' :
00968                {
00969                   struct papsiz *opapsiz = papsizes ;
00970                   struct papsiz *npapsiz ;
00971                   papsizes = 0 ;
00972                   if (*p == 0 && argv[i+1])
00973                      p = argv[++i] ;
00974                   printer = p ;
00975                   noenv = 1 ;
00976                   if (!getdefaults("")) {
00977                     /* If no config file, default the output name.  */
00978                     oname = concat ("| lpr -P", printer);
00979                   }
00980                   npapsiz = opapsiz ;
00981                   while (npapsiz && npapsiz->next)
00982                      npapsiz = npapsiz->next ;
00983                   if (npapsiz) {
00984                      npapsiz->next = papsizes ;
00985                      papsizes = opapsiz ;
00986                   }
00987               }
00988                break ;
00989 case 's':
00990                safetyenclose = (*p != '0') ;
00991                break ;
00992 case 'V':
00993                downloadpspk = (*p != '0') ;
00994                break ;
00995 case 'Z':
00996                compressed = (*p != '0') ;
00997                break ;
00998 #ifdef HPS
00999 case 'z':
01000                HPS_FLAG = (*p != '0') ;
01001                break ;
01002 #endif
01003 case '?':
01004                break ; /* We print the banner and help msg below.  */
01005 default:
01006 #ifdef KPATHSEA
01007                error(concat3 ("! Invalid option `", argv[i],
01008                               "'. Try --help for more information."));
01009 #else
01010                error(
01011      "! Bad option, not one of acdefhijklmnopqrstxyzABCDEFKMNOPSTUXYZ?") ;
01012 #endif
01013             }
01014          } else {
01015             if (*iname == 0) {
01016                register char *p ;
01017    
01018                lastext = 0 ;
01019                iname = nextstring ;
01020                p = argv[i] ;
01021               if (NAME_BEGINS_WITH_DEVICE(p)) { /* get past DOSISH drive */
01022                 *nextstring++ = *p++ ;
01023                 *nextstring++ = *p++ ;
01024               }
01025                while (*p) {
01026                   *nextstring = *p++ ;
01027                   if (*nextstring == '.')
01028                      lastext = nextstring - iname ;
01029                   else if (IS_DIR_SEP(*nextstring))
01030                      lastext = 0 ;
01031                   nextstring++ ;
01032                }
01033                *nextstring++ = '.' ;
01034                *nextstring++ = 'd' ;
01035                *nextstring++ = 'v' ;
01036                *nextstring++ = 'i' ;
01037                *nextstring++ = 0 ;
01038             } else
01039 #ifdef KPATHSEA
01040                error(concat3("! Second input filename (", argv[i],
01041                              ") specified.")) ;
01042 #else
01043                error("! Two input file names specified.") ;
01044 #endif
01045          }
01046       }
01047       if (noenv == 0) {
01048          register char *p ;
01049          struct papsiz *opapsiz = papsizes ;
01050          papsizes = 0 ;
01051         if (0 != (p = getenv("PRINTER"))) {
01052 #if defined(MSDOS) || defined(OS2)
01053             strcpy(nextstring, p) ;
01054             strcat(nextstring, ".cfg") ;
01055 #else
01056             strcpy(nextstring, "config.") ;
01057             strcat(nextstring, p) ;
01058 #endif
01059             getdefaults(nextstring) ;
01060          }
01061          {
01062             struct papsiz *npapsiz = opapsiz ;
01063             while (npapsiz && npapsiz->next)
01064                npapsiz = npapsiz->next ;
01065             if (npapsiz) {
01066                npapsiz->next = papsizes ;
01067                papsizes = opapsiz ;
01068             }
01069          }
01070       }
01071       papsizes = (struct papsiz *)revlist((void *)papsizes) ;
01072       if (queryoptions != 0) {            /* get new options */
01073          (void)fprintf(stderr, "%s %s\n", banner, banner2) ;
01074          help(1) ;
01075          queryargs();
01076          if (qargc == 1)
01077            queryoptions = 0;
01078          else {
01079            qargv[0] = argv[0];
01080            argc=qargc;
01081            argv=qargv;
01082          }
01083       }
01084    } while (queryoptions != 0) ;
01085 #endif
01086 #if (defined(KPATHSEA) && defined(DEBUG)) /* this should really be part of a subroutine */
01087    if (dd(D_FILES)) KPSE_DEBUG_SET (KPSE_DEBUG_FOPEN);
01088    if (dd(D_PATHS)) KPSE_DEBUG_SET (KPSE_DEBUG_PATHS);
01089    if (dd(D_STAT)) KPSE_DEBUG_SET (KPSE_DEBUG_STAT);
01090    if (dd(D_HASH)) KPSE_DEBUG_SET (KPSE_DEBUG_HASH);
01091    if (dd(D_EXPAND)) KPSE_DEBUG_SET (KPSE_DEBUG_EXPAND);
01092    if (dd(D_SEARCH)) KPSE_DEBUG_SET (KPSE_DEBUG_SEARCH);
01093 #endif /* DEBUG */
01094    checkenv(1) ;
01095 #ifdef KPATHSEA
01096    kpse_init_prog ("DVIPS", actualdpi, mfmode, "cmr10");
01097    kpse_make_tex_discard_errors = quiet;
01098 #endif   
01099 /*
01100  *   The logic here is a bit convoluted.  Since all `additional'
01101  *   PostScript font information files are loaded *before* the master
01102  *   one, and yet they should be able to override the master one, we
01103  *   have to add the information in the master list to the *ends* of
01104  *   the hash chain.  We do this by reversing the lists, adding them
01105  *   to the front, and then reversing them again.
01106  */
01107    revpslists() ;
01108    getpsinfo((char *)NULL) ;
01109    revpslists() ;
01110    if (!quiet)
01111       (void)fprintf(stderr, "%s %s\n", banner, banner2) ;
01112    if (*iname) {
01113       dvifile = fopen(iname, READBIN) ;
01114 /*
01115  *   Allow names like a.b.
01116  */
01117       if (dvifile == 0) {
01118          iname[strlen(iname)-4] = 0 ; /* remove the .dvi suffix */
01119          dvifile = fopen(iname, READBIN) ;
01120       }
01121    }
01122    if (oname[0] == '-' && oname[1] == 0)
01123       oname[0] = 0 ;
01124    else if (*oname == 0 && ! filter) {
01125       oname = nextstring ;
01126 #ifndef VMCMS  /* get stuff before LAST "." */
01127       lastext = strlen(iname) - 1 ;
01128       while (iname[lastext] != '.' && lastext > 0)
01129          lastext-- ;
01130       if (iname[lastext] != '.')
01131          lastext = strlen(iname) - 1 ;
01132 #else   /* for VM/CMS we take the stuff before FIRST "." */
01133       lastext = strchr(iname,'.') - iname ;
01134       if ( lastext <= 0 )     /* if no '.' in "iname" */
01135          lastext = strlen(iname) -1 ;
01136 #endif
01137 #ifdef MVSXA /* IBM: MVS/XA */
01138       if (strchr(iname, '(') != NULL  &&
01139           strchr(iname, ')') != NULL) {
01140       firstext = strchr(iname, '(') - iname + 1;
01141       lastext = strrchr(iname, ')') - iname - 1;
01142          }
01143       else {
01144       if (strrchr(iname, '.') != NULL) {
01145       lastext = strrchr(iname, '.') - iname - 1;
01146            }
01147          else lastext = strlen(iname) - 1 ;
01148       if (strchr(iname, '\'') != NULL)
01149          firstext = strchr(iname, '.') - iname + 1;
01150          else firstext = 0;
01151       }
01152 #endif  /* IBM: MVS/XA */
01153 #ifdef MVSXA /* IBM: MVS/XA */
01154       for (i=firstext; i<=lastext; i++)
01155 #else
01156       for (i=0; i<=lastext; i++)
01157 #endif
01158          *nextstring++ = iname[i] ;
01159       if (iname[lastext] != '.')
01160          *nextstring++ = '.' ;
01161 #ifndef VMCMS
01162       *nextstring++ = 'p' ;
01163       *nextstring++ = 's' ;
01164 #else  /* might as well keep things uppercase */
01165       *nextstring++ = 'P' ;
01166       *nextstring++ = 'S' ;
01167 #endif
01168       *nextstring++ = 0 ;
01169 /*
01170  *   Now we check the name, and `throw away' any prefix information.
01171  *   This means throwing away anything before (and including) a colon
01172  *   or slash.
01173  */
01174       {
01175          char *p = NAME_BEGINS_WITH_DEVICE(oname) ? oname + 2 : oname ;
01176 
01177          for (oname=p; *p && p[1]; p++)
01178             if (IS_DIR_SEP(*p))
01179                oname = p + 1 ;
01180       }
01181    }
01182 #ifdef DEBUG
01183    if (dd(D_PATHS)) {
01184 #ifdef SHORTINT
01185         (void)fprintf(stderr,"input file %s output file %s swmem %ld\n",
01186 #else /* ~SHORTINT */
01187            (void)fprintf(stderr,"input file %s output file %s swmem %d\n",
01188 #endif /* ~SHORTINT */
01189            iname, oname, swmem) ;
01190 #ifndef KPATHSEA
01191    (void)fprintf(stderr,"tfm path %s\npk path %s\n", tfmpath, pkpath) ;
01192    (void)fprintf(stderr,"fig path %s\nvf path %s\n", figpath, vfpath) ;
01193    (void)fprintf(stderr,"config path %s\nheader path %s\n",
01194                   configpath, headerpath) ;
01195 #endif
01196 #ifdef FONTLIB
01197    (void)fprintf(stderr,"fli path %s\nfli names %s\n", flipath, fliname) ;
01198 #endif
01199    } /* dd(D_PATHS) */
01200 #endif /* DEBUG */
01201 /*
01202  *   Now we try to open the dvi file.
01203  */
01204    if (!quiet && warningmsg)
01205       error(warningmsg) ;
01206    headersready = 1 ;
01207    headerfile = (char *) (compressed? CHEADERFILE : HEADERFILE) ;
01208    (void)add_header(headerfile) ;
01209    if (*iname != 0) {
01210       fulliname = nextstring ;
01211 #ifndef IGNORE_CWD
01212       if (!IS_DIR_SEP(*iname) && !NAME_BEGINS_WITH_DEVICE(iname)) {
01213         getcwd(nextstring, MAXPATHLEN + 2);
01214         while (*nextstring++) ;
01215 #ifdef VMS           /* VMS doesn't need the '/' character appended */
01216         nextstring--;       /* so just back up one byte. */
01217 #else
01218         *(nextstring-1) = '/' ;
01219 #endif
01220       }
01221 #endif
01222       strcpy(nextstring,iname) ;
01223       while (*nextstring++) ; /* advance nextstring past iname */
01224    } else if (filter) {
01225       dvifile = stdin ;
01226       if (O_BINARY && !isatty(fileno(stdin)))
01227         SET_BINARY(fileno(stdin)) ;
01228    } else {
01229 #ifdef KPATHSEA
01230       fprintf (stderr, "Missing DVI file argument (or -f).\n");
01231       fprintf (stderr, "Try --help for more information.\n");
01232 #else
01233       help(1) ;
01234 #endif
01235       exit(1) ;
01236    }
01237    initcolor() ;
01238    if (dvifile==NULL) {
01239       extern char errbuf[];
01240       (void)sprintf(errbuf,"! DVI file <%s> can't be opened.", iname) ;
01241       error("! DVI file can't be opened.") ;
01242    }
01243    if (fseek(dvifile, 0L, 0) < 0)
01244       error("! DVI file must not be a pipe.") ;
01245 #ifdef FONTLIB
01246    fliload();    /* read the font libaries */
01247 #endif
01248 /*
01249  *   Now we do our main work.
01250  */
01251    swmem += fontmem ;
01252    if (maxdrift < 0) {
01253       if (actualdpi <= 599)
01254          maxdrift = actualdpi / 100 ;
01255       else if (actualdpi < 1199)
01256          maxdrift = actualdpi / 200 + 3 ;
01257       else
01258          maxdrift = actualdpi / 400 + 6 ;
01259    }
01260    if (vmaxdrift < 0) {
01261       if (vactualdpi <= 599)
01262          vmaxdrift = vactualdpi / 100 ;
01263       else if (vactualdpi < 1199)
01264          vmaxdrift = vactualdpi / 200 + 3 ;
01265       else
01266          vmaxdrift = vactualdpi / 400 + 6 ;
01267    }
01268    if (dopprescan)
01269       pprescanpages() ;
01270    prescanpages() ;
01271 #if defined MSDOS || defined OS2 || defined(ATARIST)
01272    if (mfjobfile != (FILE*)NULL) {
01273      char answer[5];
01274      fputs("}\n",mfjobfile);
01275      fclose(mfjobfile);
01276      fputs("Exit to make missing fonts now (y/n)? ",stdout);
01277      fgets(answer,4,stdin);
01278      if (*answer=='y' || *answer=='Y')
01279        exit(8); /* exit with errorlevel 8 for emTeX dvidrv */
01280    }
01281 #endif
01282    if (includesfonts)
01283       (void)add_header(IFONTHEADER) ;
01284    if (usesPSfonts)
01285       (void)add_header(PSFONTHEADER) ;
01286    if (usesspecial)
01287       (void)add_header(SPECIALHEADER) ;
01288    if (usescolor)  /* IBM: color */
01289       (void)add_header(COLORHEADER) ;
01290 #ifdef HPS
01291    if (HPS_FLAG)
01292       (void)add_header(HPSHEADER) ;
01293 #endif
01294    sects = sections ;
01295    totalpages *= collatedcopies ;
01296    if (sects == NULL || sects->next == NULL) {
01297       sectioncopies = collatedcopies ;
01298       collatedcopies = 1 ;
01299    } else {
01300       if (! sepfiles)
01301          multiplesects = 1 ;
01302    }
01303    totalpages *= pagecopies ;
01304    if (tryepsf) {
01305       if (paperfmt || landscape || manualfeed ||
01306           collatedcopies > 1 || numcopies > 1 || cropmarks ||
01307           *iname == 0 ||
01308            (totalpages > 1 && !(sepfiles && maxsecsize == 1))) {
01309          error("Can't make it EPSF, sorry") ;
01310          tryepsf = 0 ;
01311       }
01312    }
01313 #ifdef HPS
01314    if (HPS_FLAG)
01315       set_bitfile("head.tmp", 0) ;
01316 #endif
01317    if (! sepfiles) {
01318       initprinter(sections) ;
01319       outbangspecials() ;
01320    }
01321 
01322    for (i=0; i<collatedcopies; i++) {
01323       sects = sections ;
01324       while (sects != NULL) {
01325          if (sepfiles) {
01326             newoutname() ;
01327             if (! quiet) {
01328                if (prettycolumn + strlen(oname) + 6 > STDOUTSIZE) {
01329                   fprintf(stderr, "\n") ;
01330                   prettycolumn = 0 ;
01331                }
01332                (void)fprintf(stderr, "(-> %s) ", oname) ;
01333                prettycolumn += strlen(oname) + 6 ;
01334             }
01335 #ifdef HPS
01336             if (HPS_FLAG)
01337                set_bitfile("head.tmp", 0) ;
01338 #endif
01339             initprinter(sects) ;
01340             outbangspecials() ;
01341          } else if (! quiet) {
01342             if (prettycolumn > STDOUTSIZE) {
01343                fprintf(stderr, "\n") ;
01344                prettycolumn = 0 ;
01345             }
01346             (void)fprintf(stderr, ". ") ;
01347             prettycolumn += 2 ;
01348          }
01349          (void)fflush(stderr) ;
01350          dosection(sects, sectioncopies) ;
01351          sects = sects->next ;
01352          if (sepfiles) {
01353 #ifdef HPS
01354             if (HPS_FLAG)
01355                finish_hps() ;
01356 #endif
01357             cleanprinter() ;
01358         }
01359       }
01360    }
01361    if (! sepfiles) {
01362 #ifdef HPS
01363       if (HPS_FLAG)
01364          finish_hps() ;
01365 #endif
01366       cleanprinter() ;
01367    }
01368    if (! quiet)
01369       (void)fprintf(stderr, "\n") ;
01370 #ifdef DEBUG
01371    if (dd(D_MEM)) {
01372 #ifdef SHORTINT
01373       fprintf(stderr, "Total memory allocated:  %ld\n", totalalloc) ;
01374 #else
01375       fprintf(stderr, "Total memory allocated:  %d\n", totalalloc) ;
01376 #endif
01377    }
01378 #endif
01379    return 0 ;
01380    /*NOTREACHED*/
01381 }
01382 #ifdef VMS
01383 #include "[.vms]vmscli.c"
01384 #endif
01385 
01386 #ifdef VMCMS  /* IBM: VM/CMS */
01387 #include "dvipscms.h"
01388 #endif
01389 
01390 #ifdef MVSXA  /* IBM: MVS/XA */
01391 #include "dvipsmvs.h"
01392 #endif