home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Tex / Dvi / dvipssrc.zoo / dvips.c < prev    next >
C/C++ Source or Header  |  1991-04-22  |  19KB  |  637 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58. /*
  59.  *   This is the main routine.
  60.  */
  61. #ifndef DEFRES
  62. #define DEFRES (300)
  63. #endif
  64.  
  65. #include "structures.h" /* The copyright notice there is included too! */
  66. #ifdef VMS
  67. #define GLOBAL globaldef
  68. #include climsgdef
  69. #include ctype
  70. #include descrip
  71. #endif
  72. /*
  73.  *   First we define some globals.
  74.  */
  75. #ifdef VMS
  76.     static char ofnme[252],infnme[252],pap[40],thh[20];
  77. #endif
  78. fontdesctype *fonthead ;      /* list of all fonts mentioned so far */
  79. fontdesctype *curfnt ;        /* the currently selected font */
  80. sectiontype *sections ;       /* sections to process document in */
  81. Boolean manualfeed ;          /* manual feed? */
  82. Boolean compressed ;          /* compressed? */
  83. Boolean safetyenclose ;       /* enclose in save/restore for stupid spoolers? */
  84. Boolean removecomments = 1 ;  /* remove comments from included PS? */
  85. Boolean nosmallchars ;        /* disable small char optimization for X4045? */
  86. int collatedcopies = 1 ;      /* how many collated copies? */
  87. int sectioncopies = 1 ;       /* how many times to repeat each section? */
  88. shalfword linepos = 0 ;       /* where are we on the line being output? */
  89. integer maxpages ;            /* the maximum number of pages */
  90. Boolean notfirst, notlast ;   /* true if a first page was specified */
  91. Boolean sendcontrolD ;        /* should we send a control D at end? */
  92. integer firstpage ;           /* the number of the first page if specified */
  93. integer lastpage ;
  94. integer firstseq ;
  95. integer lastseq ;
  96. int numcopies ;               /* number of copies of each page to print */
  97. char *oname ;                 /* output file name */
  98. char *iname ;                 /* dvi file name */
  99. char *strings ;               /* strings for program */
  100. char *nextstring, *maxstring ; /* string pointers */
  101. FILE *dvifile, *bitfile ;     /* dvi and output files */
  102. quarterword *curpos ;         /* current position in virtual character packet */
  103. quarterword *curlim ;         /* final byte in virtual character packet */
  104. fontmaptype *ffont ;          /* first font in current frame */
  105. real conv ;                   /* conversion ratio, pixels per DVI unit */
  106. real vconv ;                  /* conversion ratio, pixels per DVI unit */
  107. real alpha ;                  /* conversion ratio, DVI unit per TFM unit */
  108. integer mag ;                 /* the magnification of this document */
  109. Boolean overridemag ;         /* substitute for mag value in DVI file? */
  110. int actualdpi = DEFRES ;      /* the actual resolution of the printer */
  111. int vactualdpi = DEFRES ;      /* the actual resolution of the printer */
  112. int maxdrift ;                /* max pixels away from true rounded position */
  113. int vmaxdrift ;                /* max pixels away from true rounded position */
  114. char *paperfmt                /* paper format */
  115. #ifdef DEFPFMT
  116.     = DEFPFMT ;
  117. #else
  118.     ;
  119. #endif
  120. int landscape = 0 ;           /* landscape mode */
  121. integer fontmem ;             /* memory remaining in printer */
  122. integer pagecount ;           /* page counter for the sections */
  123. integer pagenum ;             /* the page number we currently look at */
  124. long bytesleft ;              /* number of bytes left in raster */
  125. quarterword *raster ;         /* area for raster manipulations */
  126. integer hh, vv ;              /* horizontal and vertical pixel positions */
  127. char *tfmpath = TFMPATH ;     /* pointer to directories for tfm files */
  128. char *pkpath = PKPATH ;       /* pointer to directories for pk files */
  129. char *vfpath = VFPATH ;       /* pointer to directories for vf files */
  130. char *figpath = FIGPATH ;     /* pointer to directories for figure files */
  131. char *headerpath = HEADERPATH ; /* pointer to directories for header files */
  132. char *configpath = CONFIGPATH;  /* where to find config files */
  133. #ifdef SEARCH_SUBDIRECTORIES
  134. char *fontsubdirpath = FONTSUBDIRPATH ;
  135. #endif
  136. #ifdef FONTLIB
  137. char *flipath = FLIPATH ;     /* pointer to directories for fli files */
  138. char *fliname = FLINAME ;     /* pointer to names of fli files */
  139. #endif
  140. integer swmem ;               /* font memory in the PostScript printer */
  141. int quiet ;                   /* should we only print errors to stderr? */
  142. int filter ;                  /* act as filter default output to stdout,
  143.                                                default input to stdin? */
  144. int prettycolumn ;            /* the column we are at when running pretty */
  145. int totalpages = 0 ;          /* total number of pages */
  146. Boolean reverse ;             /* are we going reverse? */
  147. Boolean usesPSfonts ;         /* do we use local PostScript fonts? */
  148. Boolean usesspecial ;         /* do we use \special? */
  149. Boolean headers_off ;         /* do we send headers or not? */
  150. char *headerfile ;            /* default header file */
  151. char *warningmsg ;            /* a message to write, if set in config file */
  152. Boolean multiplesects ;       /* more than one section? */
  153. Boolean disablecomments ;     /* should we suppress any EPSF comments? */
  154. char *printer ;               /* what printer to send this to? */
  155. char *mfmode ;                /* default MF mode */
  156. frametype frames[MAXFRAME] ;  /* stack for virtual fonts */
  157. fontdesctype *baseFonts[256] ; /* base fonts for dvi file */
  158. integer pagecost;               /* memory used on the page being prescanned */
  159. int delchar;                    /* characters to delete from prescanned page */
  160. integer fsizetol;               /* max dvi units error for psfile font sizes */
  161. Boolean includesfonts;          /* are fonts used in included psfiles? */
  162. fontdesctype *fonthd[MAXFONTHD];/* list headers for included fonts of 1 name */
  163. int nextfonthd;                 /* next unused fonthd[] index */
  164. char xdig[256];                 /* table for reading hexadecimal digits */
  165. char banner[] = BANNER ;        /* our startup message */
  166. Boolean noenv ;                 /* ignore PRINTER envir variable? */
  167. extern int dontmakefont ;
  168. #ifdef DEBUG
  169. integer debug_flag = 0;
  170. #endif /* DEBUG */
  171. /*
  172.  *   This routine calls the following externals:
  173.  */
  174. extern void outbangspecials() ;
  175. extern void prescanpages() ;
  176. extern void initprinter() ;
  177. extern void cleanprinter() ;
  178. extern void dosection() ;
  179. extern void getdefaults() ;
  180. extern void cmdout() ;
  181. extern void numout() ;
  182. extern int add_header() ;
  183. extern char *strcpy() ;
  184. extern void checkenv() ;
  185. extern void getpsinfo() ;
  186. #ifdef FONTLIB
  187. extern void fliload() ;
  188. #endif
  189. /*
  190.  *   This error routine prints an error message; if the first
  191.  *   character is !, it aborts the job.
  192.  */
  193. static char *progname ;
  194. void
  195. error(s)
  196.     char *s ;
  197. {
  198.    extern void exit() ;
  199.  
  200.    (void)fprintf(stderr, "%s: %s\n", progname, s) ;
  201.    if (*s=='!') {
  202.       if (bitfile != NULL) {
  203.          cleanprinter() ;
  204.       }
  205.       exit(1) ; /* fatal */
  206.    }
  207. }
  208.  
  209. /*
  210.  *   Initialize sets up all the globals and data structures.
  211.  */
  212. void
  213. initialize()
  214. {
  215.    extern char *malloc() ;
  216.    int i;
  217.    char *s;
  218.  
  219.    nextfonthd = 0;
  220.    for (i=0; i<256; i++)
  221.       xdig[i] = 0;
  222.    i = 0;
  223.    for (s="0123456789ABCDEF"; *s!=0; s++)
  224.       xdig[*s] = i++;
  225.    i = 10;
  226.    for (s="abcdef"; *s!=0; s++)
  227.       xdig[*s] = i++;
  228.    strings = malloc(STRINGSIZE) ;
  229.    if (strings == 0)
  230.       error("! no memory for strings") ;
  231.    maxpages = 100000 ;
  232.    numcopies = 1 ;
  233.    nextstring = strings ;
  234.    iname = strings ;
  235.    *nextstring++ = 0 ;
  236.    maxstring = strings + STRINGSIZE - 200 ;
  237.    bitfile = NULL ;
  238.    bytesleft = 0 ;
  239.    swmem = SWMEM ;
  240.    oname = OUTPATH ;
  241.    sendcontrolD = 0 ;
  242.    multiplesects = 0 ;
  243.    disablecomments = 0 ;
  244.    maxdrift = -1 ;
  245.    vmaxdrift = -1 ;
  246. }
  247. /*
  248.  *   This routine copies a string into the string `pool', safely.
  249.  */
  250. char *
  251. newstring(s)
  252.    char *s ;
  253. {
  254.    int l ;
  255.  
  256.    if (s == NULL)
  257.       return(NULL) ;
  258.    l = strlen(s) ;
  259.    if (nextstring + l >= maxstring)
  260.       error("! out of string space") ;
  261.    (void)strcpy(nextstring, s) ;
  262.    s = nextstring ;
  263.    nextstring += l + 1 ;
  264.    return(s) ;
  265. }
  266. /*
  267.  *   Finally, our main routine.
  268.  */
  269. #ifdef VMS
  270. main()
  271. #else
  272. void main(argc, argv)
  273.     int argc ;
  274.     char *argv[] ;
  275. #endif
  276. {
  277.    extern void exit() ;
  278.    int i, lastext = -1 ;
  279.    register sectiontype *sects ;
  280.  
  281. #ifdef VMS
  282.    progname = &thh[0] ;
  283.    strcpy(progname,"DVIPS%ERROR");
  284. #else
  285.    progname = argv[0] ;
  286. /* we sneak a look at the first arg in case it's debugging */
  287. #ifdef DEBUG
  288.    if (argc > 1 && strncmp(argv[1], "-d", 2)==0) {
  289.       if (sscanf(argv[1]+2, "%d", &debug_flag)==0)
  290.          debug_flag = 0 ;
  291.    }
  292. #endif
  293. #endif
  294.    initialize() ;
  295.    checkenv(0) ;
  296.    getdefaults(CONFIGFILE) ;
  297.    getdefaults((char *)0) ;
  298. /*
  299.  *   This next whole big section of code is straightforward; we just scan
  300.  *   the options.  An argument can either immediately follow its option letter
  301.  *   or be separated by spaces.  Any argument not preceded by '-' and an
  302.  *   option letter is considered a file name; the program complains if more
  303.  *   than one file name is given, and uses stdin if none is given.
  304.  */
  305. #ifdef VMS
  306. vmscli();
  307. #else
  308.    for (i=1; i<argc; i++) {
  309.       if (*argv[i]=='-') {
  310.          char *p=argv[i]+2 ;
  311.          char c=argv[i][1] ;
  312.          switch (c) {
  313. case 'c' :
  314.             if (*p == 0 && argv[i+1])
  315.                p = argv[++i] ;
  316.             if (sscanf(p, "%d", &numcopies)==0)
  317.                error("! Bad number of copies option (-c).") ;
  318.             break ;
  319. case 'd' :
  320. #ifdef DEBUG
  321.         if (*p == 0 && argv[i+1])
  322.            p = argv[++i];
  323.         if (sscanf(p, "%d", &debug_flag)==0)
  324.            error("! Bad debug option (-d).");
  325.         break;
  326. #else
  327.             error("not compiled in debug mode") ;
  328.             break ;
  329. #endif /* DEBUG */
  330. case 'e' :
  331.             if (*p == 0 && argv[i+1])
  332.                p = argv[++i] ;
  333.             if (sscanf(p, "%d", &maxdrift)==0 || maxdrift<0)
  334.                error("! Bad maxdrift option (-e).") ;
  335.         vmaxdrift = maxdrift;
  336.             break ;
  337. case 'f' :
  338.             filter = (*p != '0') ;
  339.             if (filter)
  340.                oname = "" ;
  341.             noenv = 1 ;
  342.             sendcontrolD = 0 ;
  343.             break ;
  344. case 'h' : case 'H' :
  345.             if (*p == 0 && argv[i+1])
  346.                p = argv[++i] ;
  347.             if (strcmp(p, "-") == 0)
  348.                headers_off = 1 ;
  349.             else
  350.                (void)add_header(p) ;
  351.             break ;
  352. case 'm' :
  353.             manualfeed = (*p != '0') ;
  354.             break ;
  355. case 'n' :
  356.             if (*p == 0 && argv[i+1])
  357.                p = argv[++i] ;
  358. #ifdef SHORTINT
  359.             if (sscanf(p, "%ld", &maxpages)==0)
  360. #else    /* ~SHORTINT */
  361.             if (sscanf(p, "%d", &maxpages)==0)
  362. #endif    /* ~SHORTINT */
  363.                error("! Bad number of pages option (-n).") ;
  364.             break ;
  365. case 'o' : case 'O' :
  366.             if (*p == 0 && argv[i+1] && *argv[i+1]!='-')
  367.                p = argv[++i] ;
  368.             oname = p ;
  369.             noenv = 1 ;
  370.             sendcontrolD = 0 ;
  371.             break ;
  372. case 'p' :
  373.             if (*p == 0 && argv[i+1])
  374.                p = argv[++i] ;
  375. #ifdef SHORTINT
  376.             switch(sscanf(p, "%d.%d", &firstpage, &firstseq)) {
  377. #else    /* ~SHORTINT */
  378.             switch(sscanf(p, "%ld.%ld", &firstpage, &firstseq)) {
  379. #endif    /* ~SHORTINT */
  380. case 1:        firstseq = 0 ;
  381. case 2:        break ;
  382. default:
  383.                error("! Bad first page option (-p).") ;
  384.             }
  385.             notfirst = 1 ;
  386.             break ;
  387. case 'l':
  388.             if (*p == 0 && argv[i+1])
  389.                p = argv[++i] ;
  390. #ifdef SHORTINT
  391.             switch(sscanf(p, "%d.%d", &lastpage, &lastseq)) {
  392. #else    /* ~SHORTINT */
  393.             switch(sscanf(p, "%ld.%ld", &lastpage, &lastseq)) {
  394. #endif    /* ~SHORTINT */
  395. case 1:        lastseq = 0 ;
  396. case 2:        break ;
  397. default:
  398.                error("! Bad last page option (-p).") ;
  399.             }
  400.             notlast = 1 ;
  401.             break ;
  402. case 'q' : case 'Q' :
  403.             quiet = (*p != '0') ;
  404.             break ;
  405. case 'r' :
  406.             reverse = (*p != '0') ;
  407.             break ;
  408. case 't' :
  409.             if (*p == 0 && argv[i+1])
  410.                p = argv[++i] ;
  411.             if (strcmp(p, "landscape") == 0)
  412.                landscape = 1;
  413.             else
  414.                paperfmt = p ;
  415.             break ;
  416. case 'x' :
  417.             if (*p == 0 && argv[i+1])
  418.                p = argv[++i] ;
  419.             if (sscanf(p, "%d", &mag)==0 || mag < 10 ||
  420.                        mag > 100000)
  421.                error("! Bad magnification parameter (-x).") ;
  422.             overridemag = 1 ;
  423.             break ;
  424. case 'C' :
  425.             if (*p == 0 && argv[i+1])
  426.                p = argv[++i] ;
  427.             if (sscanf(p, "%d", &collatedcopies)==0)
  428.                error("! Bad number of collated copies option (-C).") ;
  429.             break ;
  430. case 'D' :
  431.             if (*p == 0 && argv[i+1])
  432.                p = argv[++i] ;
  433.             if (sscanf(p, "%d", &actualdpi)==0 || actualdpi < 10 ||
  434.                        actualdpi > 10000)
  435.                error("! Bad dpi parameter (-D).") ;
  436.         vactualdpi = actualdpi;
  437.             break ;
  438. case 'K' :
  439.             removecomments = (*p != '0') ;
  440.             break ;
  441. case 'U' :
  442.             nosmallchars = (*p != '0') ;
  443.             break ;
  444. case 'X' :
  445.             if (*p == 0 && argv[i+1])
  446.                p = argv[++i] ;
  447.             if (sscanf(p, "%d", &actualdpi)==0 || actualdpi < 10 ||
  448.                        actualdpi > 10000)
  449.                error("! Bad dpi parameter (-D).") ;
  450.             break ;
  451. case 'Y' :
  452.             if (*p == 0 && argv[i+1])
  453.                p = argv[++i] ;
  454.             if (sscanf(p, "%d", &vactualdpi)==0 || vactualdpi < 10 ||
  455.                        vactualdpi > 10000)
  456.                error("! Bad dpi parameter (-D).") ;
  457.         vactualdpi = vactualdpi;
  458.             break ;
  459. case 'F' :
  460.             sendcontrolD = (*p != '0') ;
  461.             break ;
  462. case 'M':
  463.             dontmakefont = 1 ;
  464.             break ;
  465. case 'N' :
  466.             disablecomments = (*p != '0') ;
  467.             break ;
  468. case 'P' :
  469.             if (*p == 0 && argv[i+1])
  470.                p = argv[++i] ;
  471.             printer = p ;
  472.             noenv = 1 ;
  473.             getdefaults("") ;
  474.             break ;
  475. case 'R' :
  476.             reverse = 0 ;
  477.             break ;
  478. case 's' :
  479.             safetyenclose = (*p != '0') ;
  480.             break ;
  481. case 'Z' :
  482.             compressed = (*p != '0') ;
  483.             break ;
  484. case '?' :
  485.             (void)fprintf(stderr, banner) ;
  486.             break ;
  487. default:
  488.             error("! Bad option, not one of cefhlmnopqrtxCDFKNPUXYZ?") ;
  489.          }
  490.       } else {
  491.          if (*iname == 0) {
  492.             register char *p ;
  493.  
  494.             lastext = 0 ;
  495.             iname = nextstring ;
  496.             p = argv[i] ;
  497.             while (*p) {
  498.                *nextstring = *p++ ;
  499.                if (*nextstring == '.')
  500.                   lastext = nextstring - iname ;
  501.                else if (*nextstring == '/' || *nextstring == ':')
  502.                   lastext = 0 ;
  503.                nextstring++ ;
  504.             }
  505.             if (lastext == 0) {
  506.                lastext = nextstring - iname ;
  507.                *nextstring++ = '.' ;
  508.                *nextstring++ = 'd' ;
  509.                *nextstring++ = 'v' ;
  510.                *nextstring++ = 'i' ;
  511.             }
  512.             *nextstring++ = 0 ;
  513.          } else
  514.             error("! Two input file names specified.") ;
  515.       }
  516.    }
  517.    if (noenv == 0) {
  518.       register char *p ;
  519.       extern char *getenv() ;
  520.       if (p = getenv("PRINTER")) {
  521.          strcpy(nextstring, "config.") ;
  522.          strcat(nextstring, p) ;
  523.          getdefaults(nextstring) ;
  524.       }
  525.    }
  526. #endif
  527.    checkenv(1) ;
  528.    getpsinfo() ;
  529.    if (!quiet)
  530.       (void)fprintf(stderr, banner) ;
  531.    if (oname[0] == '-' && oname[1] == 0)
  532.       oname[0] = 0 ;
  533.    if (*oname == 0 && ! filter) {
  534.       oname = nextstring ;
  535.       for (i=0; i<=lastext; i++)
  536.          *nextstring++ = iname[i] ;
  537.       *nextstring++ = 'p' ;
  538.       *nextstring++ = 's' ;
  539.       *nextstring++ = 0 ;
  540.    }
  541. #ifdef DEBUG
  542.    if (dd(D_PATHS)) {
  543. #ifdef SHORTINT
  544.     (void)fprintf(stderr,"input file %s output file %s swmem %ld\n",
  545. #else /* ~SHORTINT */
  546.        (void)fprintf(stderr,"input file %s output file %s swmem %d\n",
  547. #endif /* ~SHORTINT */
  548.            iname, oname, swmem) ;
  549.    (void)fprintf(stderr,"tfm path %s\npk path %s\n", tfmpath, pkpath) ;
  550.    (void)fprintf(stderr,"fig path %s\nvf path %s\n", figpath, vfpath) ;
  551.    (void)fprintf(stderr,"config path %s\nheader path %s\n", 
  552.                   configpath, headerpath) ;
  553. #ifdef FONTLIB
  554.    (void)fprintf(stderr,"fli path %s\nfli names %s\n", flipath, fliname) ;
  555. #endif
  556.    } /* dd(D_PATHS) */
  557. #endif /* DEBUG */
  558. /*
  559.  *   Now we try to open the dvi file.
  560.  */
  561.    if (warningmsg)
  562.       error(warningmsg) ;
  563.    headerfile = (compressed? CHEADERFILE : HEADERFILE) ;
  564.    (void)add_header(headerfile) ;
  565.    if (*iname != 0)
  566.       dvifile = fopen(iname, READBIN) ;
  567.    else if (filter)
  568.       dvifile = stdin;
  569.    else
  570.       error("! No input filename supplied.") ;
  571.    if (dvifile==NULL)
  572.       error("! DVI file can't be opened.") ;
  573. #ifdef FONTLIB
  574.    fliload();    /* read the font libaries */
  575. #endif
  576. /*
  577.  *   Now we do our main work.
  578.  */
  579.    if (maxdrift < 0) {
  580.       if (actualdpi <= 599)
  581.          maxdrift = actualdpi / 100 ;
  582.       else if (actualdpi < 1199)
  583.          maxdrift = actualdpi / 200 + 3 ;
  584.       else
  585.          maxdrift = actualdpi / 400 + 6 ;
  586.    }
  587.    if (vmaxdrift < 0) {
  588.       if (vactualdpi <= 599)
  589.          vmaxdrift = vactualdpi / 100 ;
  590.       else if (vactualdpi < 1199)
  591.          vmaxdrift = vactualdpi / 200 + 3 ;
  592.       else
  593.          vmaxdrift = vactualdpi / 400 + 6 ;
  594.    }
  595.    prescanpages() ;
  596.    if (includesfonts)
  597.       (void)add_header(IFONTHEADER) ;
  598.    if (usesPSfonts)
  599.       (void)add_header(PSFONTHEADER) ;
  600.    if (usesspecial)
  601.       (void)add_header(SPECIALHEADER) ;
  602.    sects = sections ;
  603.    if (sects == NULL || sects->next == NULL) {
  604.       sectioncopies = collatedcopies ;
  605.       collatedcopies = 1 ;
  606.    } else {
  607.       totalpages *= collatedcopies ;
  608.       multiplesects = 1 ;
  609.    }
  610.    initprinter() ;
  611.    outbangspecials() ;
  612.    for (i=0; i<collatedcopies; i++) {
  613.       sects = sections ;
  614.       while (sects != NULL) {
  615.          if (! quiet) {
  616.             if (prettycolumn > 77) {
  617.                fprintf(stderr, "\n") ;
  618.                prettycolumn = 0 ;
  619.             }
  620.             (void)fprintf(stderr, ". ") ;
  621.             prettycolumn += 2 ;
  622.          }
  623.          (void)fflush(stderr) ;
  624.          dosection(sects, sectioncopies) ;
  625.          sects = sects->next ;
  626.       }
  627.    }
  628.    cleanprinter() ;
  629.    if (! quiet)
  630.       (void)fprintf(stderr, "\n") ;
  631.    exit(0) ;
  632.    /*NOTREACHED*/
  633. }
  634. #ifdef VMS
  635. #include "vms/vmscli.c"
  636. #endif
  637.