home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / unixtex-6.1b-src.tgz / tar.out / contrib / unixtex / dvipsk / resident.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  20KB  |  713 lines

  1. /*   For use with emTeX set FONTPATH to "TEXTFM"
  2.  */
  3. #ifndef FONTPATH
  4. #define FONTPATH "TEXFONTS"
  5. #endif
  6.  
  7. /*
  8.  *   This code reads in and handles the defaults for the program from the
  9.  *   file config.sw.  This entire file is a bit kludgy, sorry.
  10.  */
  11. #include "dvips.h" /* The copyright notice in that file is included too! */
  12. #include "paths.h"
  13. #include <kpathsea/c-pathch.h>
  14. #include <kpathsea/pathsearch.h>
  15. #include <kpathsea/tex-file.h>
  16.  
  17. /*
  18.  *   This is the structure definition for resident fonts.  We use
  19.  *   a small and simple hash table to handle these.  We don't need
  20.  *   a big hash table.
  21.  */
  22. struct resfont *reshash[RESHASHPRIME] ;
  23. /*
  24.  *   These are the external routines we use.
  25.  */
  26. extern void error() ;
  27. extern integer scalewidth() ;
  28. extern int tfmload() ;
  29. extern FILE *search() ;
  30. extern shalfword pkbyte() ;
  31. extern integer pkquad() ;
  32. extern integer pktrio() ;
  33. extern Boolean pkopen() ;
  34. extern char *getenv() ;
  35. extern char *newstring() ;
  36. extern int add_header() ;
  37. extern int add_name() ;
  38. extern char *get_name() ;
  39. extern int system() ;
  40. extern void handlepapersize() ;
  41. extern void checkstrings() ;
  42. void getpsinfo() ;
  43. extern void *revlist() ;
  44. /*
  45.  *   These are the external variables we use.
  46.  */
  47. #ifdef DEBUG
  48. extern integer debug_flag;
  49. #endif  /* DEBUG */
  50. extern integer pagecopies ;
  51. extern int overridemag ;
  52. extern long bytesleft ;
  53. extern quarterword *raster ;
  54. extern FILE *pkfile ;
  55. extern char *oname ;
  56. extern Boolean downloadpspk ;
  57. extern integer swmem, fontmem ;
  58. extern Boolean noenv ;
  59. #ifdef FONTLIB
  60. extern char *flipath, *fliname ;
  61. #endif
  62. extern char *paperfmt ; 
  63. extern char *nextstring ;
  64. extern char *maxstring ;
  65. extern char *warningmsg ;
  66. extern Boolean disablecomments ;
  67. extern Boolean compressed ;
  68. extern int quiet ;
  69. extern int filter ;
  70. extern Boolean reverse ;
  71. extern Boolean usesPSfonts ;
  72. extern Boolean nosmallchars ;
  73. extern Boolean removecomments ;
  74. extern Boolean safetyenclose ;
  75. extern Boolean dopprescan ;
  76. extern integer maxsecsize ;
  77. extern integer mag ;
  78. extern Boolean sepfiles ;
  79. extern int actualdpi ;
  80. extern int vactualdpi ;
  81. extern int maxdrift ;
  82. extern int vmaxdrift ;
  83. extern char *printer ;
  84. extern char *mfmode ;
  85. extern int mfmode_option;
  86. extern int oname_option;
  87. extern Boolean sendcontrolD ;
  88. extern unsigned lastresortsizes[] ;
  89. extern integer hoff, voff ;
  90. extern struct papsiz *papsizes ;
  91. extern Boolean secure ;
  92. extern integer hpapersize, vpapersize ;
  93. extern int landscape ;
  94. /*
  95.  *   To maintain a list of document fonts, we use the following
  96.  *   pointer.
  97.  */
  98. struct header_list *ps_fonts_used ;
  99. /*
  100.  *   Our hash routine.
  101.  */
  102. int
  103. hash(s)
  104.    char *s ;
  105. {
  106.    int h = 12 ;
  107.  
  108.    while (*s != 0)
  109.       h = (h + h + *s++) % RESHASHPRIME ;
  110.    return(h) ;
  111. }
  112. /*
  113.  *   Reverse the hash chains.
  114.  */
  115. void
  116. revpslists() {
  117.    register int i ;
  118.    for (i=0; i<RESHASHPRIME; i++)
  119.       reshash[i] = (struct resfont *)revlist(reshash[i]) ;
  120. }
  121. /*
  122.  *   cleanres() marks all resident fonts as not being yet sent.
  123.  */
  124. void
  125. cleanres() {
  126.    register int i ;
  127.    register struct resfont *p ;
  128.    for (i=0; i<RESHASHPRIME; i++)
  129.       for (p=reshash[i]; p; p=p->next)
  130.          p->sent = 0 ;
  131. }
  132. /*
  133.  *   The routine that looks up a font name.
  134.  */
  135. struct resfont *
  136. lookup(name)
  137.    char *name ;
  138. {
  139.    struct resfont *p ;
  140.  
  141.    for (p=reshash[hash(name)]; p!=NULL; p=p->next)
  142.       if (strcmp(p->Keyname, name)==0)
  143.          return(p) ;
  144.    return(NULL) ;
  145. }
  146. /*
  147.  *   This routine adds an entry.
  148.  */
  149. void
  150. add_entry(TeXname, PSname, specinfo, downloadinfo)
  151.    char *TeXname, *PSname, *specinfo, *downloadinfo ;
  152. {
  153.    struct resfont *p ;
  154.    int h ;
  155.  
  156.    if (PSname == NULL)
  157.       PSname = TeXname ;
  158.    p = (struct resfont *)mymalloc((integer)sizeof(struct resfont)) ;
  159.    p->Keyname = TeXname ;
  160.    p->PSname = PSname ;
  161.    p->TeXname = TeXname ;
  162.    p->specialinstructions = specinfo ;
  163.    if (downloadinfo && *downloadinfo)
  164.       p->downloadheader = downloadinfo ;
  165.    else
  166.       p->downloadheader = 0 ;
  167.    h = hash(TeXname) ;
  168.    p->next = reshash[h] ;
  169.    p->sent = 0 ;
  170.    reshash[h] = p ;
  171. }
  172. /*
  173.  *   Now our residentfont routine.  Returns the number of characters in
  174.  *   this font, based on the TFM file.
  175.  */
  176. extern char *infont ;
  177. int
  178. residentfont(curfnt)
  179.         register fontdesctype *curfnt ;
  180. {
  181.    register shalfword i ;
  182.    struct resfont *p ;
  183.  
  184. /*
  185.  *   First we determine if we can find this font in the resident list.
  186.  */
  187.    if (*curfnt->area)
  188.       return 0 ; /* resident fonts never have a nonstandard font area */
  189.    if ((p=lookup(curfnt->name))==NULL)
  190.       return 0 ;
  191. /*
  192.  *   This is not yet the correct way to do things, but it is useful as it
  193.  *   is so we leave it in.  The problem:  if resident Times-Roman is
  194.  *   re-encoded, then it will be downloaded as bitmaps; this is not
  195.  *   right.  The solution will be to introduce two types of `<'
  196.  *   directives, one that downloads fonts and one that downloads
  197.  *   short headers that are innocuous.
  198.  */
  199.    if (p->downloadheader && downloadpspk) {
  200. #ifdef DEBUG
  201.       if (dd(D_FONTS))
  202.          (void)fprintf(stderr,"Using PK font %s for <%s>.\n",
  203.                                      curfnt->name, p->PSname) ;
  204. #endif  /* DEBUG */
  205.       return 0 ;
  206.    }
  207. /*
  208.  *   We clear out some pointers:
  209.  */
  210. #ifdef DEBUG
  211.    if (dd(D_FONTS))
  212.         (void)fprintf(stderr,"Font %s <%s> is resident.\n",
  213.                                      curfnt->name, p->PSname) ;
  214. #endif  /* DEBUG */
  215.    curfnt->resfont = p ;
  216.    curfnt->name = p->TeXname ;
  217.    for (i=0; i<256; i++) {
  218.       curfnt->chardesc[i].TFMwidth = 0 ;
  219.       curfnt->chardesc[i].packptr = NULL ;
  220.       curfnt->chardesc[i].pixelwidth = 0 ;
  221.       curfnt->chardesc[i].flags = 0 ;
  222.    }
  223.    add_name(p->PSname, &ps_fonts_used) ;
  224. /*
  225.  *   We include the font here.  But we only should need to include the
  226.  *   font if we have a stupid spooler; smart spoolers should be able
  227.  *   to supply it automatically.
  228.  */
  229.    if (p->downloadheader) {
  230.       char *cp = p->downloadheader ;
  231.       char *q ;
  232.  
  233.       infont = p->PSname ;
  234.       while (1) {
  235.          q = cp ;
  236.          while (*cp && *cp != ' ')
  237.             cp++ ;
  238.          if (*cp) {
  239.             *cp = 0 ;
  240.             add_header(q) ;
  241.             *cp++ = ' ' ;
  242.          } else {
  243.             add_header(q) ;
  244.             break ;
  245.          }
  246.          infont = 0 ;
  247.       }
  248.       infont = 0 ;
  249.    }
  250.    i = tfmload(curfnt) ;
  251.    if (i < 0)
  252.       i = 1 ;
  253.    usesPSfonts = 1 ;
  254.    return(i) ;
  255. }
  256. #define INLINE_SIZE (500)
  257. static char was_inline[INLINE_SIZE] ;
  258. void
  259. bad_config() {
  260.    error("Error in config file:") ;
  261.    (void)fprintf(stderr, "%s\n", was_inline) ;
  262.    exit(1) ;
  263. }
  264.  
  265. /*
  266.  *   We use this function so we can support strings delimited by
  267.  *   double quotes with spaces in them.  We also accept strings
  268.  *   with spaces in them, but kill off any spaces at the end.
  269.  */
  270. char *configstring(s, nullok)
  271. char *s ;
  272. int nullok ;
  273. {
  274.    char tstr[300] ;
  275.    char *p = tstr ;
  276.  
  277.    while (*s && *s <= ' ')
  278.       s++ ;
  279.    if (*s == '"') {
  280.       s++ ;
  281.       while (*s != 10 && *s != 0 && *s != '"' && p < tstr+290)
  282.          *p++ = *s++ ;
  283.    } else {
  284.       while (*s && p < tstr+290)
  285.          *p++ = *s++ ;
  286.       while (*(p-1) <= ' ' && p > tstr)
  287.          p-- ;
  288.    }
  289.    *p = 0 ;
  290.    if (p == tstr && ! nullok)
  291.       bad_config() ;
  292.    return newstring(tstr) ;
  293. }
  294.  
  295. /* We use this in `getdefaults' to modify the kpathsea structure for the
  296.    paths we read.  See kpathsea/tex-file.[ch].  */
  297. #define SET_CLIENT_PATH(filefmt, val) \
  298.   kpse_format_info[filefmt].client_path = xstrdup (val)
  299.  
  300. /*
  301.  *   Now we have the getdefaults routine.
  302.  */
  303. static char *psmapfile = PSMAPFILE ;
  304. void
  305. getdefaults(s)
  306. char *s ;
  307. {
  308.    FILE *deffile ;
  309.    char PSname[300] ;
  310.    register char *p ;
  311.    int i, j ;
  312.    integer hsiz, vsiz ;
  313.    int canaddtopaper = 0 ;
  314.  
  315.    if (printer == NULL) {
  316.       if (s) {
  317.          strcpy(PSname, s) ;
  318.       } else {
  319.          strcpy(PSname, DVIPSRC) ;
  320.       }
  321.    } else {
  322. #if defined(MSDOS) || defined(OS2)
  323.       strcpy(PSname, printer) ;
  324.       strcat(PSname, ".cfg") ;
  325. #else
  326.       strcpy(PSname, "config.") ;
  327.       strcat(PSname, printer) ;
  328. #endif
  329.    }
  330.    if ((deffile=search(configpath,PSname,READ))!=NULL) {
  331.       while (fgets(was_inline, INLINE_SIZE, deffile)!=NULL) {
  332. /*
  333.  *   We need to get rid of the newline.
  334.  */
  335.        for (p=was_inline; *p; p++) ;
  336.        if (p > was_inline) *(p-1) = 0 ;
  337.        if (was_inline[0] != '@')
  338.           canaddtopaper = 0 ;
  339.        switch (was_inline[0]) {
  340. /*
  341.  *   Handling paper size information:
  342.  *
  343.  *      If line is empty, then we clear out the paper size information
  344.  *      we have so far.
  345.  *
  346.  *      If it is `@+', then we add to the current paper size info.
  347.  *
  348.  *      If it is `name hsize vsize', then we start a new definition.
  349.  */
  350. case '@' :
  351.          p = was_inline + 1 ;
  352.          while (*p && *p <= ' ') p++ ;
  353.          if (*p == 0) {
  354.             papsizes = 0 ; /* throw away memory */
  355.          } else if (*p == '+') {
  356.             if (canaddtopaper == 0)
  357.                error(
  358.       " @+ in config files must immediately following a @ lines") ;
  359.             else {
  360.                *(nextstring-1) = '\n' ;/* IBM: VM/CMS - changed 10 to "\n" */
  361.                p++ ;
  362.                while (*p && *p == ' ') p++ ;
  363.                strcpy(nextstring, p) ;
  364.                nextstring += strlen(p) + 1 ;
  365.             }
  366.          } else {
  367.             struct papsiz *ps ;
  368.             
  369.             ps = (struct papsiz *)mymalloc((integer)sizeof(struct papsiz)) ;
  370.             ps->next = papsizes ;
  371.             papsizes = ps ;
  372.             ps->name = p ;
  373.             while (*p && *p > ' ')
  374.                p++ ;
  375.             *p++ = 0 ;
  376.             ps->name = newstring(ps->name) ;
  377.             while (*p && *p <= ' ') p++ ;
  378.             handlepapersize(p, &hsiz, &vsiz) ;
  379.             ps->xsize = hsiz ;
  380.             ps->ysize = vsiz ;
  381.             ps->specdat = nextstring++ ;
  382.             canaddtopaper = 1 ;
  383.          }
  384.          break ;
  385. case 'a' :
  386.          dopprescan = (was_inline[1] != '0') ;
  387.          break ;
  388. case 'b':
  389. #ifdef SHORTINT
  390.          if (sscanf(was_inline+1, "%ld", &pagecopies) != 1) bad_config() ;
  391. #else
  392.          if (sscanf(was_inline+1, "%d", &pagecopies) != 1) bad_config() ;
  393. #endif
  394.          if (pagecopies < 1 || pagecopies > 1000)
  395.             bad_config() ;
  396.          break ;
  397. case 'm' :
  398. #ifdef SHORTINT
  399.          if (sscanf(was_inline+1, "%ld", &swmem) != 1) bad_config() ;
  400. #else   /* ~SHORTINT */
  401.          if (sscanf(was_inline+1, "%d", &swmem) != 1) bad_config() ;
  402. #endif  /* ~SHORTINT */
  403.          swmem += fontmem ; /* grab headers we've seen already */
  404.          break ;
  405. case 'M' :
  406.          /* If the user specified a -mode, don't replace it.  */
  407.          if (!mfmode_option)
  408.            mfmode = configstring(was_inline+1, 0) ;
  409.          break ;
  410. case 'o' :
  411.      if (!oname_option) {
  412.            oname = configstring(was_inline+1, 1) ;
  413.            if (*oname && oname[strlen(oname)-1] == ':')
  414.               sendcontrolD = 1 ; /* if we send to a device, *we* are spooler */
  415.      }
  416.          break ;
  417. case 'O' :
  418.          p = was_inline + 1 ;
  419.          handlepapersize(p, &hoff, &voff) ;
  420.          break ;
  421. #ifdef FONTLIB
  422. case 'L' : 
  423.          {
  424.             char tempname[300] ;
  425.             extern char *fliparse() ;
  426.             if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  427.             else {
  428.                flipath = getpath(fliparse(PSname,tempname), flipath);
  429.                fliname = newstring(tempname) ;
  430.             }
  431.      }
  432.          break ;
  433. #endif
  434. case 'T' : 
  435.          if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  436.          else SET_CLIENT_PATH (kpse_tfm_format, PSname);
  437.          break ;
  438. case 'P' :
  439.          if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  440.          else SET_CLIENT_PATH (kpse_pk_format, PSname);
  441.          break ;
  442. case 'p' :
  443.          p = was_inline + 1 ;
  444.          while (*p && *p <= ' ')
  445.             p++ ;
  446.          if (*p == '+') {
  447.             if (sscanf(p+1, "%s", PSname) != 1) bad_config() ;
  448.             getpsinfo(PSname) ;
  449.          } else {
  450.             psmapfile = configstring(was_inline+1, 0) ;
  451.          }
  452.          break ;
  453. case 'v' : case 'V' :
  454.          if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  455.          else SET_CLIENT_PATH (kpse_vf_format, PSname);
  456.          break ;
  457. case 'S' :
  458.          if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  459.          else SET_CLIENT_PATH (kpse_pict_format, PSname);
  460.          break ;
  461. case 's':
  462.          safetyenclose = 1 ;
  463.          break ;
  464. case 'H' : 
  465.          if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  466.          else SET_CLIENT_PATH (kpse_dvips_header_format, PSname);
  467.          break ;
  468. case '%': case ' ' : case '*' : case '#' : case ';' :
  469. case '=' : case 0 : case '\n' :
  470.          break ;
  471. case 'r' :
  472.          reverse = (was_inline[1] != '0') ;
  473.          break ;
  474. /*
  475.  *   This case is for last resort font scaling; I hate this, but enough
  476.  *   people have in no uncertain terms demanded it that I'll go ahead and
  477.  *   add it.
  478.  *
  479.  *   This line must have numbers on it, resolutions, to search for the
  480.  *   font as a last resort, and then the font will be scaled.  These
  481.  *   resolutions should be in increasing order.
  482.  *
  483.  *   For most machines, just `300' is sufficient here; on the NeXT,
  484.  *   `300 400' may be more appropriate.
  485.  */
  486. case 'R':
  487.          i = 0 ;
  488.          p = was_inline + 1 ;
  489.          while (*p) {
  490.             while (*p && *p <= ' ')
  491.                p++ ;
  492.             if ('0' <= *p && *p <= '9') {
  493.                j = 0 ;
  494.                while ('0' <= *p && *p <= '9')
  495.                   j = 10 * j + (*p++ - '0') ;
  496.                if (i > 0)
  497.                   if (lastresortsizes[i-1] > j) {
  498.                      error("last resort sizes (R) must be sorted") ;
  499.                      bad_config() ;
  500.                   }
  501.                lastresortsizes[i++] = j ;
  502.             } else {
  503.                if (*p == 0)
  504.                   break ;
  505.                error("! only numbers expected on `R' line in config!") ;
  506.             }
  507.          }
  508.          lastresortsizes[i] = 0 ;
  509.          break ;
  510. case 'D' :
  511.          if (sscanf(was_inline+1, "%d", &actualdpi) != 1) bad_config() ;
  512.          if (actualdpi < 10 || actualdpi > 10000) bad_config() ;
  513.      vactualdpi = actualdpi;
  514.          break ;
  515. /*
  516.  *   Execute a command.  This can be dangerous, but can also be very useful.
  517.  */
  518. case 'E' :
  519. #ifdef SECURE
  520.          error("dvips was compiled with SECURE, which disables E in config") ;
  521. #else
  522.          if (secure) {
  523.             error("dvips -R option used, which disables E in config") ;
  524.             break ;
  525.          }
  526.          (void)system(was_inline+1) ;
  527. #endif
  528.          break ;
  529. case 'K':
  530.          removecomments = (was_inline[1] != '0') ;
  531.          break ;
  532. case 'U':
  533.          nosmallchars = (was_inline[1] != '0') ;
  534.          break ;
  535. case 'W':
  536.          for (p=was_inline+1; *p && *p <= ' '; p++) ;
  537.          if (*p)
  538.             warningmsg = newstring(p) ;
  539.          else
  540.             warningmsg = 0 ;
  541.          break ;
  542. case 'X' :
  543.          if (sscanf(was_inline+1, "%d", &actualdpi) != 1) bad_config() ;
  544.          if (actualdpi < 10 || actualdpi > 10000) bad_config() ;
  545.          break ;
  546. case 'Y' :
  547.          if (sscanf(was_inline+1, "%d", &vactualdpi) != 1) bad_config() ;
  548.          if (vactualdpi < 10 || vactualdpi > 10000) bad_config() ;
  549.          break ;
  550. case 'x': case 'y':
  551.          if (sscanf(was_inline+1, "%d", &mag) != 1) bad_config() ;
  552.          overridemag = (was_inline[0] == 'x') ? 1 : -1 ;
  553.          break ;
  554. case 'e' :
  555.          if (sscanf(was_inline+1, "%d", &maxdrift) != 1) bad_config() ;
  556.          if (maxdrift < 0) bad_config() ;
  557.      vmaxdrift = maxdrift;
  558.          break ;
  559. case 'q' : case 'Q' :
  560.          quiet = (was_inline[1] != '0') ;
  561.          break ;
  562. case 'f' : case 'F' :
  563.          filter = (was_inline[1] != '0') ;
  564.          break ;
  565. case 'h' : 
  566.          if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  567.          else (void)add_header(PSname) ;
  568.          break ;
  569. case 'i' :
  570.          if (sscanf(was_inline+1, "%d", &maxsecsize) != 1)
  571.             maxsecsize = 0 ;
  572.          sepfiles = 1 ;
  573.          break ;
  574. case 'I':
  575.          noenv = (was_inline[1] != '0') ;
  576.          break ;
  577. case 'N' :
  578.          disablecomments = (was_inline[1] != '0') ;
  579.          break ;
  580. case 'Z' :
  581.          compressed = (was_inline[1] != '0') ;
  582.          break ;
  583. case 't' :
  584.          if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config() ;
  585.          else {
  586.            if (strcmp(PSname, "landscape") == 0) {
  587.                if (hpapersize || vpapersize)
  588.                   error(
  589.             "both landscape and papersize specified; ignoring landscape") ;
  590.                else
  591.                   landscape = 1 ;
  592.             } else
  593.                paperfmt = newstring(PSname) ;
  594.          }
  595.          break ;
  596. default:
  597.          bad_config() ;
  598.       }
  599.      }
  600.      (void)fclose(deffile) ;
  601.    } else {
  602.       if (printer)
  603.         {
  604.           char msg[1000];
  605.           sprintf (msg, "! no config file for printer `%s'", printer);
  606.           error(msg);
  607.         }
  608.    }
  609. }
  610.  
  611. /*
  612.  *   If a character pointer is passed in, use that name; else, use the
  613.  *   default (possibly set) name.
  614.  */
  615. void getpsinfo(name)
  616. char *name ;
  617. {
  618.    FILE *deffile ;
  619.    register char *p ;
  620.    char *specinfo, *downloadinfo ;
  621.    char downbuf[500] ;
  622.    char specbuf[500] ;
  623.  
  624.    if (name == 0)
  625.       name = psmapfile ;
  626.    if ((deffile=search(configpath, name, READ))!=NULL) {
  627.       while (fgets(was_inline, INLINE_SIZE, deffile)!=NULL) {
  628.          p = was_inline ;
  629.          if (*p > ' ' && *p != '*' && *p != '#' && *p != ';' && *p != '%') {
  630.             char *TeXname = NULL ;
  631.             char *PSname = NULL ;
  632.             specinfo = NULL ;
  633.             downloadinfo = NULL ;
  634.             downbuf[0] = 0 ;
  635.             specbuf[0] = 0 ;
  636.             while (*p) {
  637.                while (*p && *p <= ' ')
  638.                   p++ ;
  639.                if (*p) {
  640.                   if (*p == '"') {
  641.                      if (specinfo) {
  642.                         strcat(specbuf, specinfo) ;
  643.                         strcat(specbuf, " ") ;
  644.                      }
  645.                      specinfo = p + 1 ;
  646.                   }
  647.                   else if (*p == '<') {
  648.                      if (downloadinfo) {
  649.                         strcat(downbuf, downloadinfo) ;
  650.                         strcat(downbuf, " ") ;
  651.                      }
  652.                      while (p[1] == ' ' || p[1] == '\t')
  653.                        p++;
  654.                      downloadinfo = p + 1 ;
  655.                   } else if (TeXname)
  656.                      PSname = p ;
  657.                   else
  658.                      TeXname = p ;
  659.                   if (*p == '"') {
  660.                      p++ ;
  661.                      while (*p != '"' && *p)
  662.                         p++ ;
  663.                   } else
  664.                      while (*p > ' ')
  665.                         p++ ;
  666.                   if (*p)
  667.                      *p++ = 0 ;
  668.                }
  669.             }
  670.             if (specinfo)
  671.                strcat(specbuf, specinfo) ;
  672.             if (downloadinfo)
  673.                strcat(downbuf, downloadinfo) ;
  674.             if (TeXname) {
  675.                TeXname = newstring(TeXname) ;
  676.                specinfo = newstring(specbuf) ;
  677.                PSname = newstring(PSname) ;
  678.                downloadinfo = newstring(downbuf) ;
  679.                add_entry(TeXname, PSname, specinfo, downloadinfo) ;
  680.             }
  681.         }
  682.       }
  683.       (void)fclose(deffile) ;
  684.    }
  685.    checkstrings() ;
  686. }
  687.  
  688. #if 0
  689. /* Print the path P with label TITLE.  */
  690.  
  691. static void
  692. print_path (title, p)
  693.     string title;
  694.     string p;
  695. {
  696.   fprintf (stderr, "%s path: \t", title);
  697.   if (p == NULL)
  698.     fprintf (stderr, "(null)\n");
  699.   else if (p == NULL)
  700.     fprintf (stderr, "(empty)\n");
  701.   else
  702.     fprintf (stderr, "%s", p);
  703.   putc ('\n', stderr);
  704. }
  705. #endif
  706.  
  707. void
  708. checkenv(which)
  709.     int which ;
  710. {
  711.   /* Now irrelevant; kpathsea does all the initializations.  */
  712. }
  713.