home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / t / tex / !dvips / Documents / Fonts / Source / c / dvips < prev    next >
Encoding:
Text File  |  1995-01-20  |  36.4 KB  |  1,158 lines

  1. /*
  2.  *   This is the main routine.
  3.  */
  4. #ifndef DEFRES
  5. #define DEFRES (300)
  6. #endif
  7.  
  8. #include "dvips.h" /* The copyright notice there is included too! */
  9. #ifndef SYSV
  10. extern char *strtok() ; /* some systems don't have this in strings.h */
  11. #endif
  12. #ifdef VMS
  13. #define GLOBAL globaldef
  14. #ifdef __GNUC__
  15. #include "climsgdef.h"    /* created by hand, extracted from STARLET.MLB */
  16.             /* and put in GNU_CC:[INCLUDE.LOCAL]           */
  17. #include "ctype.h"
  18. #include "descrip.h"
  19. #else
  20. #include climsgdef
  21. #include ctype
  22. #include descrip
  23. #endif
  24. #endif
  25. /*
  26.  *   First we define some globals.
  27.  */
  28.       extern char *getenv() ;
  29. #ifdef VMS
  30.     static char ofnme[252],infnme[252],pap[40],thh[20];
  31. #endif
  32. fontdesctype *fonthead ;      /* list of all fonts mentioned so far */
  33. fontdesctype *curfnt ;        /* the currently selected font */
  34. sectiontype *sections ;       /* sections to process document in */
  35. Boolean manualfeed ;          /* manual feed? */
  36. Boolean compressed ;          /* compressed? */
  37. Boolean downloadpspk ;        /* use PK for downloaded PS fonts? */
  38. Boolean safetyenclose ;
  39.                           /* enclose in save/restore for stupid spoolers? */
  40. Boolean removecomments = 1 ;  /* remove comments from included PS? */
  41. Boolean nosmallchars ;        /* disable small char optimization for X4045? */
  42. Boolean cropmarks ;           /* add cropmarks? */
  43. Boolean abspage = 0 ;         /* are page numbers absolute? */
  44. Boolean tryepsf = 0 ;         /* should we try to make it espf? */
  45. Boolean secure = 0 ;          /* make safe for suid */
  46. int collatedcopies = 1 ;      /* how many collated copies? */
  47. int sectioncopies = 1 ;       /* how many times to repeat each section? */
  48. integer pagecopies = 1 ;          /* how many times to repeat each page? */
  49. shalfword linepos = 0 ;       /* where are we on the line being output? */
  50. integer maxpages ;            /* the maximum number of pages */
  51. Boolean notfirst, notlast ;   /* true if a first page was specified */
  52. Boolean evenpages, oddpages ; /* true if doing only even/only odd pages */
  53. Boolean pagelist ;            /* true if using page ranges */
  54. Boolean sendcontrolD ;        /* should we send a control D at end? */
  55. integer firstpage ;           /* the number of the first page if specified */
  56. integer lastpage ;
  57. integer firstseq ;
  58. integer lastseq ;
  59. integer hpapersize, vpapersize ; /* horizontal and vertical paper size */
  60. integer hoff, voff ;          /* horizontal and vertical offsets */
  61. integer maxsecsize ;          /* the maximum size of a section */
  62. integer firstboploc ;         /* where the first bop is */
  63. Boolean sepfiles ;            /* each section in its own file? */
  64. int numcopies ;               /* number of copies of each page to print */
  65. char *oname ;                 /* output file name */
  66. char *iname ;                 /* dvi file name */
  67. char *fulliname ;             /* same, with current working directory */
  68. char *strings ;               /* strings for program */
  69. char *nextstring, *maxstring ; /* string pointers */
  70. FILE *dvifile, *bitfile ;     /* dvi and output files */
  71. quarterword *curpos ;        /* current position in virtual character packet */
  72. quarterword *curlim ;         /* final byte in virtual character packet */
  73. fontmaptype *ffont ;          /* first font in current frame */
  74. real conv ;                   /* conversion ratio, pixels per DVI unit */
  75. real vconv ;                  /* conversion ratio, pixels per DVI unit */
  76. real alpha ;                  /* conversion ratio, DVI unit per TFM unit */
  77. integer mag ;                 /* the magnification of this document */
  78. integer num, den ;            /* the numerator and denominator */
  79. int overridemag ;             /* substitute for mag value in DVI file? */
  80. int actualdpi = DEFRES ;      /* the actual resolution of the printer */
  81. int vactualdpi = DEFRES ;     /* the actual resolution of the printer */
  82. int maxdrift ;                /* max pixels away from true rounded position */
  83. int vmaxdrift ;               /* max pixels away from true rounded position */
  84. char *paperfmt ;              /* command-line paper format */
  85. int landscape = 0 ;           /* landscape mode */
  86. integer fontmem ;             /* memory remaining in printer */
  87. integer pagecount ;           /* page counter for the sections */
  88. integer pagenum ;             /* the page number we currently look at */
  89. long bytesleft ;              /* number of bytes left in raster */
  90. quarterword *raster ;         /* area for raster manipulations */
  91. integer hh, vv ;              /* horizontal and vertical pixel positions */
  92.  
  93. /*-----------------------------------------------------------------------*
  94.  * The PATH definitions cannot be defined on the command line because so many
  95.  * DEFINE's overflow the DCL buffer when using the GNU CC compiler.
  96.  *-----------------------------------------------------------------------*/
  97. #if defined(VMS) && defined(__GNUC__)
  98. #include "vms_gcc_paths.h"
  99. #endif
  100. #ifdef RISCOS
  101. /* This allows us to get a file's canonical name, and indeeed to see if we have
  102.  * RISCOS 3.00 or greater and so are able to to this. */
  103. #include <kernel.h>
  104. #include <swis.h>
  105. #define MAXPATHLEN (256)
  106. static _kernel_swi_regs in_regs, out_regs ;
  107. #endif
  108.  
  109. char *infont ;                /* is the file we are downloading a font? */
  110. #ifndef PICTPATH
  111. #ifdef RISCOS
  112. #define PICTPATH "@"
  113. #else
  114. #ifndef __THINK__
  115. #define PICTPATH "."
  116. #else
  117. #define PICTPATH ":"
  118. #endif
  119. #endif
  120. #endif
  121.  
  122. char *tfmpath = TFMPATH ;     /* pointer to directories for tfm files */
  123. char *pkpath = PKPATH ;       /* pointer to directories for pk files */
  124. char *vfpath = VFPATH ;       /* pointer to directories for vf files */
  125. char *figpath = FIGPATH ;     /* pointer to directories for figure files */
  126. char *headerpath = HEADERPATH ; /* pointer to directories for header files */
  127. char *configpath = CONFIGPATH ; /* where to find config files */
  128. char *pictpath = PICTPATH  ;  /* where IFF/etc. pictures are found */
  129. #ifdef SEARCH_SUBDIRECTORIES
  130. char *fontsubdirpath = FONTSUBDIRPATH ;
  131. #endif
  132. #ifdef FONTLIB
  133. char *flipath = FLIPATH ;     /* pointer to directories for fli files */
  134. char *fliname = FLINAME ;     /* pointer to names of fli files */
  135. #endif
  136. integer swmem ;               /* font memory in the PostScript printer */
  137. int quiet ;                   /* should we only print errors to stderr? */
  138. int filter ;                  /* act as filter default output to stdout,
  139.                                                default input to stdin? */
  140. int prettycolumn ;            /* the column we are at when running pretty */
  141. int gargc ;                   /* global argument count */
  142. char **gargv ;                /* global argument vector */
  143. int totalpages = 0 ;          /* total number of pages */
  144. Boolean reverse ;             /* are we going reverse? */
  145. Boolean usesPSfonts ;         /* do we use local PostScript fonts? */
  146. Boolean usesspecial ;         /* do we use \special? */
  147. Boolean headers_off ;         /* do we send headers or not? */
  148. Boolean usescolor ;           /* IBM: color - do we use colors? */
  149. char *headerfile ;            /* default header file */
  150. char *warningmsg ;            /* a message to write, if set in config file */
  151. Boolean multiplesects ;       /* more than one section? */
  152. Boolean disablecomments ;     /* should we suppress any EPSF comments? */
  153. char *printer ;               /* what printer to send this to? */
  154. char *mfmode ;                /* default MF mode */
  155. frametype frames[MAXFRAME] ;  /* stack for virtual fonts */
  156. fontdesctype *baseFonts[256] ; /* base fonts for dvi file */
  157. integer pagecost;               /* memory used on the page being prescanned */
  158. int delchar;                    /* characters to delete from prescanned page */
  159. integer fsizetol;               /* max dvi units error for psfile font sizes */
  160. Boolean includesfonts;          /* are fonts used in included psfiles? */
  161. fontdesctype *fonthd[MAXFONTHD];/* list headers for included fonts of 1 name */
  162. int nextfonthd;                 /* next unused fonthd[] index */
  163. char xdig[256];                 /* table for reading hexadecimal digits */
  164. char banner[] = BANNER ;        /* our startup message */
  165. Boolean noenv = 0 ;             /* ignore PRINTER envir variable? */
  166. Boolean dopprescan = 0 ;        /* do we do a scan before the prescan? */
  167. integer lastheadermem ;         /* how much mem did the last header require? */
  168. extern int dontmakefont ;
  169. struct papsiz *papsizes ;       /* all available paper size */
  170. int headersready ;              /* ready to check headers? */
  171. #if defined MSDOS || defined OS2
  172. char *mfjobname = NULL;         /* name of mfjob file if given */
  173. FILE *mfjobfile = NULL;         /* mfjob file for font making instructions */
  174. #endif
  175. #ifdef DEBUG
  176. integer debug_flag = 0;
  177. #endif /* DEBUG */
  178. char queryline[256];                /* interactive query of options */
  179. int qargc;
  180. char *qargv[32];
  181. char queryoptions;
  182. /*
  183.  *   This routine calls the following externals:
  184.  */
  185. extern void outbangspecials() ;
  186. extern void prescanpages() ;
  187. extern void pprescanpages() ;
  188. extern void initprinter() ;
  189. extern void cleanprinter() ;
  190. extern void dosection() ;
  191. extern void getdefaults() ;
  192. extern void cmdout() ;
  193. extern void numout() ;
  194. extern void initcolor() ;
  195. extern int add_header() ;
  196. extern int ParsePages() ;
  197. extern void checkenv() ;
  198. extern void getpsinfo(), revpslists() ;
  199. #ifdef FONTLIB
  200. extern void fliload() ;
  201. #endif
  202. #ifdef __THINK__
  203. int dcommand(char ***);
  204. #endif
  205.  
  206. /* Declare the routine to get the current working directory.  */
  207.  
  208. #ifdef RISCOS
  209. #ifndef IGNORE_CWD
  210. char *fullpath ;
  211. #else
  212. #ifndef IGNORE_CWD
  213. #ifndef HAVE_GETCWD
  214. extern char *getwd (); /* said to be faster than getcwd (SunOS man page) */
  215. #define getcwd(b, len)  getwd(b) /* used here only when b nonnull */
  216. #else
  217. #ifdef ANSI
  218. extern char *getcwd (char *, int);
  219. #else
  220. extern char *getcwd ();
  221. #endif /* not ANSI */
  222. #endif /* not HAVE_GETWD */
  223. #if defined(SYSV) || defined(VMS) || defined(MSDOS) || defined(OS2) || defined(RISCOS)
  224. #define MAXPATHLEN (256)
  225. #else
  226. #include <sys/param.h>  /* for MAXPATHLEN */
  227. #endif
  228. #endif /* not IGNORE_CWD */
  229. #endif
  230.  
  231. static char *helparr[] = {
  232. #ifndef VMCMS
  233. "    Usage: dvips [options] filename[.dvi]",
  234. #else
  235. "    VM/CMS Usage:",
  236. "           dvips fname [ftype [fmode]] [options]",
  237. "or",
  238. "           dvips fname[.ftype[.fmode]] [options]",
  239. #endif
  240. "a*  Conserve memory, not time      y # Multiply by dvi magnification",
  241. "b # Page copies, for posters e.g.  A   Print only odd (TeX) pages",
  242. "c # Uncollated copies              B   Print only even (TeX) pages",
  243. "d # Debugging                      C # Collated copies",
  244. "e # Maxdrift value                 D # Resolution",
  245. "f*  Run as filter                  E*  Try to create EPSF",
  246. "h f Add header file                F*  Send control-D at end",
  247. "i*  Separate file per section      K*  Pull comments from inclusions",
  248. "k*  Print crop marks               M*  Don't make fonts",
  249. "l # Last page                      N*  No structured comments",
  250. "m*  Manual feed                    O c Set/change paper offset",
  251. #if defined(MSDOS) || defined(OS2)
  252. "n # Maximum number of pages        P s Load $s.cfg",
  253. #else
  254. "n # Maximum number of pages        P s Load config.$s",
  255. #endif
  256. "o f Output file                    R   Run securely",
  257. "p # First page                     S # Max section size in pages",
  258. "q*  Run quietly                    T c Specify desired page size",
  259. "r*  Reverse order of pages         U*  Disable string param trick",
  260. "s*  Enclose output in save/restore V*  Send downloadable PS fonts as PK",
  261. "t s Paper format                   X # Horizontal resolution",
  262. "x # Override dvi magnification     Y # Vertical resolution",
  263. "                                   Z*  Compress bitmap fonts",
  264. /* "-   Interactive query of options", */
  265. "    # = number   f = file   s = string  * = suffix, `0' to turn off",
  266. "    c = comma-separated dimension pair (e.g., 3.2in,-32.1cm)", 0} ;
  267. void help() {
  268.    char **p ;
  269.    for (p=helparr; *p; p++)
  270.       fprintf(stderr, " %s\n", *p) ;
  271. }
  272. /*
  273.  *   This error routine prints an error message; if the first
  274.  *   character is !, it aborts the job.
  275.  */
  276. static char *progname ;
  277. void
  278. error(s)
  279.         char *s ;
  280. {
  281.    extern void exit() ;
  282.  
  283.    if (prettycolumn > 0)
  284.         fprintf(stderr,"\n");
  285.    prettycolumn = 0;
  286.    (void)fprintf(stderr, "%s: %s\n", progname, s) ;
  287.    if (*s=='!') {
  288.       if (bitfile != NULL) {
  289.          cleanprinter() ;
  290.       }
  291.       exit(1) ; /* fatal */
  292.    }
  293. }
  294. /*
  295.  *   This is our malloc that checks the results.  We debug the
  296.  *   allocations but not the frees, since memory fragmentation
  297.  *   might be such that we can never use the free'd memory and
  298.  *   it's wise to be conservative.  The only real place we free
  299.  *   is when repacking *huge* characters anyway.
  300.  */
  301. #ifdef DEBUG
  302. static integer totalalloc = 0 ;
  303. #endif
  304. char *mymalloc(n)
  305. integer n ;
  306. {
  307.    char *p ;
  308.  
  309. #ifdef SMALLMALLOC
  310.    if (n > 65500L)
  311.       error("! can't allocate more than 64K!") ;
  312. #endif
  313.    if (n <= 0) /* catch strange 0 mallocs in flib.c without breaking code */
  314.       n = 1 ;
  315. #ifdef DEBUG
  316.    totalalloc += n ;
  317.    if (dd(D_MEM)) {
  318. #ifdef SHORTINT
  319.       fprintf(stderr, "Alloc %ld\n", n) ;
  320. #else
  321.       fprintf(stderr, "Alloc %d\n", n) ;
  322. #endif
  323.    }
  324. #endif
  325.    p = malloc(n) ;
  326.    if (p == NULL)
  327.       error("! no memory") ;
  328.    return p ;
  329. }
  330. void
  331. morestrings() {
  332.    strings = mymalloc((integer)STRINGSIZE) ;
  333.    nextstring = strings ;
  334.    maxstring = strings + STRINGSIZE - 200 ;
  335.    *nextstring++ = 0 ;
  336. }
  337. void
  338. checkstrings() {
  339.    if (nextstring - strings > STRINGSIZE / 2)
  340.       morestrings() ;
  341. }
  342. /*
  343.  *   Initialize sets up all the globals and data structures.
  344.  */
  345. void
  346. initialize()
  347. {
  348.    int i;
  349.    char *s;
  350.  
  351.    nextfonthd = 0;
  352.    for (i=0; i<256; i++)
  353.       xdig[i] = 0;
  354.    i = 0;
  355.    for (s="0123456789ABCDEF"; *s!=0; s++)
  356.       xdig[(int)*s] = i++;
  357.    i = 10;
  358.    for (s="abcdef"; *s!=0; s++)
  359.       xdig[(int)*s] = i++;
  360.    morestrings() ;
  361.    maxpages = 100000 ;
  362.    numcopies = 1 ;
  363.    iname = fulliname = strings ;
  364.    bitfile = NULL ;
  365.    bytesleft = 0 ;
  366.    swmem = SWMEM ;
  367.    oname = OUTPATH ;
  368.    sendcontrolD = 0 ;
  369.    multiplesects = 0 ;
  370.    disablecomments = 0 ;
  371.    maxdrift = -1 ;
  372.    vmaxdrift = -1 ;
  373. }
  374. /*
  375.  *   This routine copies a string into the string `pool', safely.
  376.  */
  377. char *
  378. newstring(s)
  379.    char *s ;
  380. {
  381.    int l ;
  382.  
  383.    if (s == NULL)
  384.       return(NULL) ;
  385.    l = strlen(s) ;
  386.    if (nextstring + l >= maxstring)
  387.       morestrings() ;
  388.    if (nextstring + l >= maxstring)
  389.       error("! out of string space") ;
  390.    (void)strcpy(nextstring, s) ;
  391.    s = nextstring ;
  392.    nextstring += l + 1 ;
  393.    return(s) ;
  394. }
  395. void newoutname() {
  396.    static int seq = 0 ;
  397.    static char *seqptr = 0 ;
  398.    char *p ;
  399.  
  400.    if (oname == 0 || *oname == 0)
  401.       error("! need an output file name to specify separate files") ;
  402.    if (*oname != '!' && *oname != '|') {
  403.       if (seqptr == 0) {
  404.          oname = newstring(oname) ;
  405.          seqptr = 0 ;
  406.          for (p = oname; *p; p++)
  407.             if (*p == '.')
  408.                seqptr = p + 1 ;
  409.          if (seqptr == 0)
  410.             seqptr = p ;
  411.          nextstring += 5 ; /* make room for the number, up to five digits */
  412.       }
  413.       sprintf(seqptr, "%03d", ++seq) ;
  414.    }
  415. }
  416. /*
  417.  *   This routine reverses a list, where a list is defined to be any
  418.  *   structure whose first element is a pointer to another such structure.
  419.  */
  420. VOID *revlist(p)
  421. VOID *p ;
  422. {
  423.    struct list {
  424.       struct list *next ;
  425.    } *pp = (struct list *)p, *qq = 0, *tt ;
  426.  
  427.    while (pp) {
  428.       tt = pp->next ;
  429.       pp->next = qq ;
  430.       qq = pp ;
  431.       pp = tt ;
  432.    }
  433.    return (VOID *)qq ;
  434. }
  435. /* this asks for a new set of arguments from the command line */
  436. void
  437. queryargs()
  438. {
  439.    fputs("Options: ",stdout);
  440.    fgets(queryline,256,stdin);
  441.    qargc=1;
  442.    if ( (qargv[1] = strtok(queryline," \n")) != (char *)NULL ) {
  443.       qargc=2;
  444.       while ( ((qargv[qargc] = strtok((char *)NULL," \n")) != (char *)NULL)
  445.             && (qargc < 31) )
  446.          qargc++;
  447.    }
  448.    qargv[qargc] = (char *)NULL;
  449. }
  450.  
  451. /*
  452.  *   Finally, our main routine.
  453.  */
  454. extern void handlepapersize() ;
  455. #ifdef VMS
  456. main()
  457. #else
  458. void main(argc, argv)
  459.         int argc ;
  460.         char *argv[] ;
  461. #endif
  462. {
  463.    extern void exit() ;
  464.    int i, lastext = -1 ;
  465. #ifdef MVSXA
  466.    int firstext = -1 ;
  467. #endif
  468. #ifdef RISCOS
  469.    int pathextent = -1 ;
  470. #endif
  471.    register sectiontype *sects ;
  472.  
  473. #ifdef __THINK__
  474.    argc = dcommand(&argv) ; /* do I/O stream redirection */
  475. #endif
  476. #ifdef VMS        /* Grab the command-line buffer */
  477.    short len_arg;
  478.    $DESCRIPTOR( verb_dsc, "DVIPS ");    /* assume the verb is always DVIPS */
  479.    struct dsc$descriptor_d temp_dsc = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_D, 0};
  480.  
  481.    progname = &thh[0] ;
  482.    strcpy(progname,"DVIPS%ERROR");
  483.  
  484.    lib$get_foreign( &temp_dsc, 0, &len_arg, 0);    /* Get the command line */
  485.    str$prefix(&temp_dsc, &verb_dsc);        /* prepend the VERB     */
  486.    len_arg += verb_dsc.dsc$w_length;        /* update the length    */
  487.    temp_dsc.dsc$a_pointer[len_arg] = '\0';    /* terminate the string */
  488.    gargv = &temp_dsc.dsc$a_pointer;        /* point to the buffer  */
  489.    gargc = 1 ;                    /* only one big argv    */
  490. #else
  491.    progname = argv[0] ;
  492.    gargv = argv ;
  493.    gargc = argc ;
  494. /* we sneak a look at the first arg in case it's debugging */
  495. #ifdef DEBUG
  496.    if (argc > 1 && strncmp(argv[1], "-d", 2)==0) {
  497.       if (argv[1][2]==0) {
  498.          if (sscanf(argv[2], "%d", &debug_flag)==0)
  499.             debug_flag = 0 ;
  500.       } else {
  501.          if (sscanf(argv[1]+2, "%d", &debug_flag)==0)
  502.             debug_flag = 0 ;
  503.       }
  504.    }
  505. #endif
  506. #endif
  507.    initialize() ;
  508.    checkenv(0) ;
  509.    getdefaults(CONFIGFILE) ;
  510.    getdefaults((char *)0) ;
  511. /*
  512.  *   This next whole big section of code is straightforward; we just scan
  513.  *   the options.  An argument can either immediately follow its option letter
  514.  *   or be separated by spaces.  Any argument not preceded by '-' and an
  515.  *   option letter is considered a file name; the program complains if more
  516.  *   than one file name is given, and uses stdin if none is given.
  517.  */
  518. #ifdef VMS
  519. vmscli();
  520. #else
  521.    queryoptions = 0;
  522.    do
  523.    {
  524.       for (i=1; i<argc; i++) {
  525.          if (*argv[i]=='-') {
  526.             char *p=argv[i]+2 ;
  527.             char c=argv[i][1] ;
  528.             switch (c) {
  529. case '-':
  530.                queryoptions = 1;
  531.                break;
  532. case 'a':
  533.                dopprescan = (*p != '0') ;
  534.                break ;
  535. case 'b':
  536.                if (*p == 0 && argv[i+1])
  537.                   p = argv[++i] ;
  538.                if (sscanf(p, "%d", &pagecopies)==0)
  539.                   error("! Bad number of page copies option (-b).") ;
  540.                if (pagecopies < 1 || pagecopies > 1000)
  541.                   error("! can only print one to a thousand page copies") ;
  542.                break ;
  543. case 'c' :
  544.                if (*p == 0 && argv[i+1])
  545.                   p = argv[++i] ;
  546.                if (sscanf(p, "%d", &numcopies)==0)
  547.                   error("! Bad number of copies option (-c).") ;
  548.                break ;
  549. case 'd' :
  550. #ifdef DEBUG
  551.                if (*p == 0 && argv[i+1])
  552.                   p = argv[++i];
  553.                if (sscanf(p, "%d", &debug_flag)==0)
  554.                   error("! Bad debug option (-d).");
  555.                break;
  556. #else
  557.                error("not compiled in debug mode") ;
  558.                break ;
  559. #endif /* DEBUG */
  560. case 'e' :
  561.                if (*p == 0 && argv[i+1])
  562.                   p = argv[++i] ;
  563.                if (sscanf(p, "%d", &maxdrift)==0 || maxdrift<0)
  564.                   error("! Bad maxdrift option (-e).") ;
  565.                vmaxdrift = maxdrift;
  566.                break ;
  567. case 'f' :
  568.                filter = (*p != '0') ;
  569.                if (filter)
  570.                   oname = "" ;
  571.                noenv = 1 ;
  572.                sendcontrolD = 0 ;
  573.                break ;
  574. case 'h' : case 'H' :
  575.                if (*p == 0 && argv[i+1])
  576.                   p = argv[++i] ;
  577.                if (strcmp(p, "-") == 0)
  578.                   headers_off = 1 ;
  579.                else
  580.                   (void)add_header(p) ;
  581.                break ;
  582. case 'i':
  583.                sepfiles = (*p != '0') ;
  584.                break ;
  585. case 'k':
  586.                cropmarks = (*p != '0') ;
  587.                break ;
  588. case 'R':
  589.                secure = 1 ;
  590.                break ;
  591. case 'S':
  592.                if (*p == 0 && argv[i+1])
  593.                   p = argv[++i] ;
  594.                if (sscanf(p, "%d", &maxsecsize)==0)
  595.                   error("! Bad section size arg (-S).") ;
  596.                break ;
  597. case 'm' :
  598.                manualfeed = (*p != '0') ;
  599.                break ;
  600. case 'n' :
  601.                if (*p == 0 && argv[i+1])
  602.                   p = argv[++i] ;
  603. #ifdef SHORTINT
  604.                if (sscanf(p, "%ld", &maxpages)==0)
  605. #else        /* ~SHORTINT */
  606.                if (sscanf(p, "%d", &maxpages)==0)
  607. #endif        /* ~SHORTINT */
  608.                   error("! Bad number of pages option (-n).") ;
  609.                break ;
  610. case 'o' :
  611.                if (*p == 0 && argv[i+1] && *argv[i+1]!='-')
  612.                   p = argv[++i] ;
  613.                oname = p ;
  614.                noenv = 1 ;
  615.                sendcontrolD = 0 ;
  616.                break ;
  617. case 'O' :
  618.                if (*p == 0 && argv[i+1])
  619.                   p = argv[++i] ;
  620.                handlepapersize(p, &hoff, &voff) ;
  621.                break ;
  622. case 'T' :
  623.                if (*p == 0 && argv[i+1])
  624.                   p = argv[++i] ;
  625.                handlepapersize(p, &hpapersize, &vpapersize) ;
  626.                if (landscape) {
  627.                   error(
  628.               "both landscape and papersize specified; ignoring landscape") ;
  629.                   landscape = 0 ;
  630.                }
  631.                break ;
  632. case 'p' :
  633. #if defined MSDOS || defined OS2
  634.                /* check for emTeX job file (-pj=filename) */
  635.                if (*p == 'j') {
  636.                  p++;
  637.                  if (*p == '=')
  638.                    p++;
  639.                  mfjobname = newstring(p);
  640.                  break;
  641.                }
  642.                /* must be page number instead */
  643. #endif
  644.                if (*p == 'p') {  /* a -pp specifier for a page list? */
  645.                   p++ ;
  646.                   if (*p == 0 && argv[i+1])
  647.                      p = argv[++i] ;
  648.                   if (ParsePages(p))
  649.                      error("! Bad page list specifier (-pp).") ;
  650.                   pagelist = 1 ;
  651.                   break ;
  652.                }
  653.                if (*p == 0 && argv[i+1])
  654.                   p = argv[++i] ;
  655.                if (*p == '=') {
  656.                   abspage = 1 ;
  657.                   p++ ;
  658.                }
  659. #ifdef SHORTINT
  660.                switch(sscanf(p, "%ld.%ld", &firstpage, &firstseq)) {
  661. #else        /* ~SHORTINT */
  662.                switch(sscanf(p, "%d.%d", &firstpage, &firstseq)) {
  663. #endif        /* ~SHORTINT */
  664. case 1:           firstseq = 0 ;
  665. case 2:           break ;
  666. default:
  667.                   error("! Bad first page option (-p).") ;
  668.                }
  669.                notfirst = 1 ;
  670.                break ;
  671. case 'l':
  672.                if (*p == 0 && argv[i+1])
  673.                   p = argv[++i] ;
  674.                if (*p == '=') {
  675.                   abspage = 1 ;
  676.                   p++ ;
  677.                }
  678. #ifdef SHORTINT
  679.                switch(sscanf(p, "%ld.%ld", &lastpage, &lastseq)) {
  680. #else        /* ~SHORTINT */
  681.                switch(sscanf(p, "%d.%d", &lastpage, &lastseq)) {
  682. #endif        /* ~SHORTINT */
  683. case 1:           lastseq = 0 ;
  684. case 2:           break ;
  685. default:
  686.                   error("! Bad last page option (-p).") ;
  687.                }
  688.                notlast = 1 ;
  689.                break ;
  690. case 'A':
  691.                oddpages = 1 ;
  692.                break ;
  693. case 'B':
  694.                evenpages = 1 ;
  695.                break ;
  696. case 'q' : case 'Q' :
  697.                quiet = (*p != '0') ;
  698.                break ;
  699. case 'r' :
  700.                reverse = (*p != '0') ;
  701.                break ;
  702. case 't' :
  703.                if (*p == 0 && argv[i+1])
  704.                   p = argv[++i] ;
  705.                if (strcmp(p, "landscape") == 0) {
  706.                   if (hpapersize || vpapersize)
  707.                      error(
  708.              "both landscape and papersize specified; ignoring landscape") ;
  709.                   else
  710.                      landscape = 1 ;
  711.                } else
  712.                   paperfmt = p ;
  713.                break ;
  714. case 'x' : case 'y' :
  715.                if (*p == 0 && argv[i+1])
  716.                   p = argv[++i] ;
  717.                if (sscanf(p, "%d", &mag)==0 || mag < 10 ||
  718.                           mag > 100000)
  719.                   error("! Bad magnification parameter (-x).") ;
  720.                overridemag = (c == 'x' ? 1 : -1) ;
  721.                break ;
  722. case 'C' :
  723.                if (*p == 0 && argv[i+1])
  724.                   p = argv[++i] ;
  725.                if (sscanf(p, "%d", &collatedcopies)==0)
  726.                   error("! Bad number of collated copies option (-C).") ;
  727.                break ;
  728. case 'D' :
  729.                if (*p == 0 && argv[i+1])
  730.                   p = argv[++i] ;
  731.                if (sscanf(p, "%d", &actualdpi)==0 || actualdpi < 10 ||
  732.                           actualdpi > 10000)
  733.                   error("! Bad dpi parameter (-D).") ;
  734.                vactualdpi = actualdpi;
  735.                break ;
  736. case 'E' :
  737.                tryepsf = (*p != '0') ;
  738.                break ;
  739. case 'K' :
  740.                removecomments = (*p != '0') ;
  741.                break ;
  742. case 'U' :
  743.                nosmallchars = (*p != '0') ;
  744.                break ;
  745. case 'X' :
  746.                if (*p == 0 && argv[i+1])
  747.                   p = argv[++i] ;
  748.                if (sscanf(p, "%d", &actualdpi)==0 || actualdpi < 10 ||
  749.                           actualdpi > 10000)
  750.                   error("! Bad dpi parameter (-D).") ;
  751.                break ;
  752. case 'Y' :
  753.                if (*p == 0 && argv[i+1])
  754.                   p = argv[++i] ;
  755.                if (sscanf(p, "%d", &vactualdpi)==0 || vactualdpi < 10 ||
  756.                           vactualdpi > 10000)
  757.                   error("! Bad dpi parameter (-D).") ;
  758.                vactualdpi = vactualdpi;
  759.                break ;
  760. case 'F' :
  761.                sendcontrolD = (*p != '0') ;
  762.                break ;
  763. case 'M':
  764.                dontmakefont = (*p != '0') ;
  765.                break ;
  766. case 'N' :
  767.                disablecomments = (*p != '0') ;
  768.                break ;
  769. case 'P' :
  770.                if (*p == 0 && argv[i+1])
  771.                   p = argv[++i] ;
  772.                printer = p ;
  773.                noenv = 1 ;
  774.                getdefaults("") ;
  775.                break ;
  776. case 's' :
  777.                safetyenclose = (*p != '0') ;
  778.                break ;
  779. case 'V':
  780.                downloadpspk = (*p != '0') ;
  781.                break ;
  782. case 'Z' :
  783.                compressed = (*p != '0') ;
  784.                break ;
  785. case '?' :
  786.                (void)fprintf(stderr, banner) ;
  787.                help() ;
  788.                break ;
  789. default:
  790.                error(
  791.               "! Bad option, not one of acdefhiklmnopqrstxCDEFKMNOPSTUXYZ?") ;
  792.             }
  793.          } else {
  794.             if (*iname == 0) {
  795.                register char *p ;
  796.  
  797.                lastext = 0 ;
  798.                iname = nextstring ;
  799.                p = argv[i] ;
  800.                while (*p) {
  801.                   *nextstring = *p++ ;
  802.                   if (*nextstring == '.')
  803.                      lastext = nextstring - iname ;
  804.                   else if (*nextstring == '/' || *nextstring == ':')
  805.                      lastext = 0 ;
  806.                   nextstring++ ;
  807.                }
  808.                *nextstring++ = '.' ;
  809.                *nextstring++ = 'd' ;
  810.                *nextstring++ = 'v' ;
  811.                *nextstring++ = 'i' ;
  812.                *nextstring++ = 0 ;
  813.             } else
  814.                error("! Two input file names specified.") ;
  815.          }
  816.       }
  817.       if (noenv == 0) {
  818.          register char *p ;
  819.  
  820.          if (0 != (p = getenv("PRINTER"))) {
  821. #if defined(MSDOS) || defined(OS2)
  822.             strcpy(nextstring, p) ;
  823.             strcat(nextstring, ".cfg") ;
  824. #else
  825.             strcpy(nextstring, "config.") ;
  826.             strcat(nextstring, p) ;
  827. #endif
  828.             getdefaults(nextstring) ;
  829.          }
  830.       }
  831.       if (queryoptions != 0) {            /* get new options */
  832.          (void)fprintf(stderr, banner) ;
  833.          help() ;
  834.          queryargs();
  835.          if (qargc == 1)
  836.            queryoptions = 0;
  837.          else {
  838.            qargv[0] = argv[0];
  839.            argc=qargc;
  840.            argv=qargv;
  841.          }
  842.       }
  843.    } while (queryoptions != 0) ;
  844. #endif
  845.    checkenv(1) ;
  846. /*
  847.  *   The logic here is a bit convoluted.  Since all `additional'
  848.  *   PostScript font information files are loaded *before* the master
  849.  *   one, and yet they should be able to override the master one, we
  850.  *   have to add the information in the master list to the *ends* of
  851.  *   the hash chain.  We do this by reversing the lists, adding them
  852.  *   to the front, and then reversing them again.
  853.  */
  854.    revpslists() ;
  855.    getpsinfo((char *)NULL) ;
  856.    revpslists() ;
  857.    if (!quiet)
  858.       (void)fprintf(stderr, banner) ;
  859.    if (*iname) {
  860.       dvifile = fopen(iname, READBIN) ;
  861. /*
  862.  *   Allow names like a.b.
  863.  */
  864.       if (dvifile == 0) {
  865.          iname[strlen(iname)-4] = 0 ; /* remove the .dvi suffix */
  866.          dvifile = fopen(iname, READBIN) ;
  867.       }
  868.    }
  869.    if (oname[0] == '-' && oname[1] == 0)
  870.       oname[0] = 0 ;
  871.    if (*oname == 0 && ! filter) {
  872.       oname = nextstring ;
  873. #ifndef VMCMS  /* get stuff before LAST "." */
  874.       lastext = strlen(iname) - 1 ;
  875.       while (iname[lastext] != '.' && lastext > 0)
  876.          lastext-- ;
  877.       if (iname[lastext] != '.')
  878.          lastext = strlen(iname) - 1 ;
  879. #else   /* for VM/CMS we take the stuff before FIRST "." */
  880.       lastext = strchr(iname,'.') - iname ;
  881.       if ( lastext <= 0 )     /* if no '.' in "iname" */
  882.          lastext = strlen(iname) -1 ;
  883. #endif
  884.       }
  885. #endif
  886. #ifdef MVSXA /* IBM: MVS/XA */
  887.       if (strchr(iname, '(') != NULL  &&
  888.           strchr(iname, ')') != NULL) {
  889.       firstext = strchr(iname, '(') - iname + 1;
  890.       lastext = strrchr(iname, ')') - iname - 1;
  891.          }
  892.       else {
  893.       if (strrchr(iname, '.') != NULL) {
  894.       lastext = strrchr(iname, '.') - iname - 1;
  895.            }
  896.          else lastext = strlen(iname) - 1 ;
  897.       if (strchr(iname, '\'') != NULL)
  898.          firstext = strchr(iname, '.') - iname + 1;
  899.          else firstext = 0;
  900.       }
  901. #endif  /* IBM: MVS/XA */
  902. #ifdef MVSXA /* IBM: MVS/XA */
  903.       for (i=firstext; i<=lastext; i++)
  904. #else
  905.       for (i=0; i<=lastext; i++)
  906. #endif
  907.          *nextstring++ = iname[i] ;
  908.       if (iname[lastext] != '.')
  909.          *nextstring++ = '.' ;
  910. #ifndef VMCMS
  911. #if defined(RISCOS) && defined(GHOST)
  912.       *nextstring++ = '_' ;
  913. #endif
  914.       *nextstring++ = 'p' ;
  915.       *nextstring++ = 's' ;
  916. #else  /* might as well keep things uppercase */
  917.       *nextstring++ = 'P' ;
  918.       *nextstring++ = 'S' ;
  919. #endif
  920.       *nextstring++ = 0 ;
  921. #ifdef RISCOS      /* In RISC OS if we are given an absolute filename then we */
  922. #ifndef IGNORE_CWD /* will use its path as cwd to try to avoid the "1 cwd" problem */
  923.       if (lastext > -1) {
  924.         char *colon;
  925.         pathextent = lastext - 1 ;
  926.         while (pathextent >= 0 && iname[pathextent] != DIRSEP)
  927.            pathextent-- ;
  928.         if (*iname == '$' || *iname == '&'
  929.             || (colon = strchr (iname,':')) && *colon++ == ':'
  930.             && iname[pathextent] == DIRSEP) {
  931.             fullpath = nextstring ;
  932.             for (i=0; i<pathextent; i++)
  933.                *nextstring++ = iname[i] ;
  934.             *nextstring++ = 0 ;
  935.          }
  936.          else
  937.             oname += pathextent + 1 ;
  938.       }
  939. #endif
  940. #endif
  941.  
  942. /*
  943.  *   Now we check the name, and `throw away' any prefix information.
  944.  *   This means throwing away anything before (and including) a colon
  945.  *   or slash.
  946.  */
  947.  
  948. #ifndef RISCOS /* This has been done above we are looking for a fake cwd. */
  949.       {
  950.          char *p ;
  951.  
  952.          for (p=oname; *p && p[1]; p++)
  953.             if (*p == ':' || *p == DIRSEP)
  954.                oname = p + 1 ;
  955.       }
  956. #endif
  957.  
  958. #ifdef DEBUG
  959.    if (dd(D_PATHS)) {
  960. #ifdef SHORTINT
  961.         (void)fprintf(stderr,"input file %s output file %s swmem %ld\n",
  962. #else /* ~SHORTINT */
  963.            (void)fprintf(stderr,"input file %s output file %s swmem %d\n",
  964. #endif /* ~SHORTINT */
  965.            iname, oname, swmem) ;
  966.    (void)fprintf(stderr,"tfm path %s\npk path %s\n", tfmpath, pkpath) ;
  967.    (void)fprintf(stderr,"fig path %s\nvf path %s\n", figpath, vfpath) ;
  968.    (void)fprintf(stderr,"config path %s\nheader path %s\n",
  969.                   configpath, headerpath) ;
  970. #ifdef FONTLIB
  971.    (void)fprintf(stderr,"fli path %s\nfli names %s\n", flipath, fliname) ;
  972. #endif
  973. #ifdef RISCOS
  974.    (void)fprintf(stderr,"\"Current\" directory %s\n", fullpath ? fullpath : "@") ;
  975. #endif
  976.    } /* dd(D_PATHS) */
  977. #endif /* DEBUG */
  978. /*
  979.  *   Now we try to open the dvi file.
  980.  */
  981.    if (warningmsg)
  982.       error(warningmsg) ;
  983.    headersready = 1 ;
  984.    headerfile = (compressed? CHEADERFILE : HEADERFILE) ;
  985.    (void)add_header(headerfile) ;
  986.    if (*iname != 0) {
  987.       fulliname = nextstring ;
  988. #ifndef IGNORE_CWD
  989. #ifdef RISCOS
  990.       if (_kernel_osbyte(129,0,0xff) >= 0xa3) {
  991.          in_regs.r[0] = 37 ;
  992.          in_regs.r[1] = (int) iname ;
  993.          in_regs.r[2] = (int) fulliname ;
  994.          in_regs.r[3] = in_regs.r[4] = 0 ;
  995.          in_regs.r[5] = MAXPATHLEN + 2 ;
  996.          if (_kernel_swi(OS_FSControl,&in_regs,&out_regs))
  997.              error ("! can't get full path name of DVI file.") ;
  998.       }
  999.       else {
  1000.          strcpy(nextstring,iname) ;
  1001.       }
  1002.       while (*nextstring++) ;
  1003. #else
  1004.       if (*iname != '/') {
  1005.         getcwd(nextstring, MAXPATHLEN + 2);
  1006.         while (*nextstring++) ;
  1007. #ifdef VMS        /* VMS doesn't need the '/' character appended */
  1008.         nextstring--;    /* so just back up one byte. */
  1009. #else
  1010.         *(nextstring-1) = '/' ;
  1011. #endif
  1012.       }
  1013. #endif
  1014. #endif
  1015. #ifndef RISCOS
  1016.       strcpy(nextstring,iname) ;
  1017.       while (*nextstring++) ; /* advance nextstring past fulliname */
  1018. #endif
  1019.    } else if (filter)
  1020.       dvifile = stdin;
  1021.    else {
  1022.       help() ;
  1023.       exit(0) ;
  1024.    }
  1025.    initcolor() ;
  1026.    if (dvifile==NULL) {
  1027.       extern char errbuf[];
  1028.       (void)sprintf(errbuf,"! DVI file <%s> can't be opened.", iname) ;
  1029.       error("! DVI file can't be opened.") ;
  1030.    }
  1031.    if (fseek(dvifile, 0L, 0) < 0)
  1032.       error("! DVI file must not be a pipe.") ;
  1033. #ifdef FONTLIB
  1034.    fliload();    /* read the font libaries */
  1035. #endif
  1036. /*
  1037.  *   Now we do our main work.
  1038.  */
  1039.    swmem += fontmem ;
  1040.    if (maxdrift < 0) {
  1041.       if (actualdpi <= 599)
  1042.          maxdrift = actualdpi / 100 ;
  1043.       else if (actualdpi < 1199)
  1044.          maxdrift = actualdpi / 200 + 3 ;
  1045.       else
  1046.          maxdrift = actualdpi / 400 + 6 ;
  1047.    }
  1048.    if (vmaxdrift < 0) {
  1049.       if (vactualdpi <= 599)
  1050.          vmaxdrift = vactualdpi / 100 ;
  1051.       else if (vactualdpi < 1199)
  1052.          vmaxdrift = vactualdpi / 200 + 3 ;
  1053.       else
  1054.          vmaxdrift = vactualdpi / 400 + 6 ;
  1055.    }
  1056.    if (dopprescan)
  1057.       pprescanpages() ;
  1058.    prescanpages() ;
  1059. #if defined MSDOS || defined OS2
  1060.    if (mfjobfile != (FILE*)NULL) {
  1061.      char answer[5];
  1062.      fputs("}\n",mfjobfile);
  1063.      fclose(mfjobfile);
  1064.      fputs("Exit to make missing fonts now (y/n)? ",stdout);
  1065.      fgets(answer,4,stdin);
  1066.      if (*answer=='y' || *answer=='Y')
  1067.        exit(8); /* exit with errorlevel 8 for emTeX dvidrv */
  1068.    }
  1069. #endif
  1070.    if (includesfonts)
  1071.       (void)add_header(IFONTHEADER) ;
  1072.    if (usesPSfonts)
  1073.       (void)add_header(PSFONTHEADER) ;
  1074.    if (usesspecial)
  1075.       (void)add_header(SPECIALHEADER) ;
  1076.    if (usescolor)  /* IBM: color */
  1077.       (void)add_header(COLORHEADER) ;
  1078.    papsizes = (struct papsiz *)revlist((void *)papsizes) ;
  1079.    sects = sections ;
  1080.    totalpages *= collatedcopies ;
  1081.    if (sects == NULL || sects->next == NULL) {
  1082.       sectioncopies = collatedcopies ;
  1083.       collatedcopies = 1 ;
  1084.    } else {
  1085.       if (! sepfiles)
  1086.          multiplesects = 1 ;
  1087.    }
  1088.    totalpages *= pagecopies ;
  1089.    if (tryepsf) {
  1090.       if (totalpages != 1 || paperfmt || landscape || manualfeed ||
  1091.           collatedcopies > 1 || numcopies > 1 || cropmarks ||
  1092.           *iname == 0) {
  1093.          error("Can't make it EPSF, sorry") ;
  1094.          tryepsf = 0 ;
  1095.       }
  1096.    }
  1097.    if (! sepfiles) {
  1098.       initprinter(0) ;
  1099.       outbangspecials() ;
  1100.    }
  1101.    for (i=0; i<collatedcopies; i++) {
  1102.       sects = sections ;
  1103.       while (sects != NULL) {
  1104.          if (sepfiles) {
  1105.             newoutname() ;
  1106.             if (! quiet) {
  1107.                if (prettycolumn + strlen(oname) + 6 > STDOUTSIZE) {
  1108.                   fprintf(stderr, "\n") ;
  1109.                   prettycolumn = 0 ;
  1110.                }
  1111.                (void)fprintf(stderr, "(-> %s) ", oname) ;
  1112.                prettycolumn += strlen(oname) + 6 ;
  1113.             }
  1114.             initprinter(sects->numpages) ;
  1115.             outbangspecials() ;
  1116.          } else if (! quiet) {
  1117.             if (prettycolumn > STDOUTSIZE) {
  1118.                fprintf(stderr, "\n") ;
  1119.                prettycolumn = 0 ;
  1120.             }
  1121.             (void)fprintf(stderr, ". ") ;
  1122.             prettycolumn += 2 ;
  1123.          }
  1124.          (void)fflush(stderr) ;
  1125.          dosection(sects, sectioncopies) ;
  1126.          sects = sects->next ;
  1127.          if (sepfiles)
  1128.             cleanprinter() ;
  1129.       }
  1130.    }
  1131.    if (! sepfiles)
  1132.       cleanprinter() ;
  1133.    if (! quiet)
  1134.       (void)fprintf(stderr, "\n") ;
  1135. #ifdef DEBUG
  1136.    if (dd(D_MEM)) {
  1137. #ifdef SHORTINT
  1138.       fprintf(stderr, "Total memory allocated:  %ld\n", totalalloc) ;
  1139. #else
  1140.       fprintf(stderr, "Total memory allocated:  %d\n", totalalloc) ;
  1141. #endif
  1142.    }
  1143. #endif
  1144.    exit(0) ;
  1145.    /*NOTREACHED*/
  1146. }
  1147. #ifdef VMS
  1148. #include "[]vmscli.c"
  1149. #endif
  1150.  
  1151. #ifdef VMCMS  /* IBM: VM/CMS */
  1152. #include "dvipscms.h"
  1153. #endif
  1154.  
  1155. #ifdef MVSXA  /* IBM: MVS/XA */
  1156. #include "dvipsmvs.h"
  1157. #endif
  1158.