diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
commit | 487ca4806cc046076293cf6cc5fbba0db282bac7 (patch) | |
tree | 847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/dvipsk/resident.c | |
parent | a3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff) |
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvipsk/resident.c')
-rw-r--r-- | Build/source/texk/dvipsk/resident.c | 1222 |
1 files changed, 1222 insertions, 0 deletions
diff --git a/Build/source/texk/dvipsk/resident.c b/Build/source/texk/dvipsk/resident.c new file mode 100644 index 00000000000..80610b02c90 --- /dev/null +++ b/Build/source/texk/dvipsk/resident.c @@ -0,0 +1,1222 @@ +/* For use with emTeX set FONTPATH to "TEXTFM" + */ +#ifndef FONTPATH +#define FONTPATH "TEXFONTS" +#endif + +/* + * This code reads in and handles the defaults for the program from the + * file config.sw. This entire file is a bit kludgy, sorry. + */ +#include "dvips.h" /* The copyright notice in that file is included too! */ +#include "paths.h" +#ifdef KPATHSEA +#include <kpathsea/c-ctype.h> +#include <kpathsea/c-pathch.h> +#include <kpathsea/c-stat.h> +#include <kpathsea/pathsearch.h> +#include <kpathsea/tex-file.h> +#include <kpathsea/variable.h> +#endif +/* + * This is the structure definition for resident fonts. We use + * a small and simple hash table to handle these. We don't need + * a big hash table. + */ +struct resfont *reshash[RESHASHPRIME] ; +/* + * These are the external routines we use. + */ +#include "protos.h" +/* + * These are the external variables we use. + */ +extern char *realnameoffile ; +#ifdef DEBUG +extern integer debug_flag; +#endif /* DEBUG */ +extern integer pagecopies ; +extern int overridemag ; +extern long bytesleft ; +extern quarterword *raster ; +extern FILE *pkfile ; +extern char *oname ; +extern integer swmem, fontmem ; +#ifndef KPATHSEA +extern char *tfmpath, *pictpath ; +extern char *pkpath ; +extern char *vfpath ; +extern char *figpath ; +extern char *configpath ; +extern char *headerpath ; +#ifdef SEARCH_SUBDIRECTORIES +extern char *fontsubdirpath ; +#endif +#endif +extern Boolean noenv ; +extern Boolean downloadpspk ; +#ifdef FONTLIB +extern char *flipath, *fliname ; +#endif +extern char *paperfmt ; +extern char *nextstring ; +extern char *maxstring ; +extern char *warningmsg ; +extern Boolean disablecomments ; +extern Boolean compressed ; +extern Boolean partialdownload ; +extern int quiet ; +extern int filter ; +extern Boolean reverse ; +extern Boolean usesPSfonts ; +extern Boolean nosmallchars ; +extern Boolean removecomments ; +extern Boolean safetyenclose ; +extern Boolean dopprescan ; +extern integer maxsecsize ; +extern double mag ; +extern Boolean sepfiles ; +extern int actualdpi ; +extern int vactualdpi ; +extern int maxdrift ; +extern int vmaxdrift ; +extern char *printer ; +extern char *mfmode, *mflandmode ; +extern int mfmode_option; +extern int secure_option; +extern int oname_option; +extern Boolean sendcontrolD ; +#ifdef SHIFTLOWCHARS +extern Boolean shiftlowchars ; +#endif +extern unsigned lastresortsizes[] ; +extern integer hoff, voff ; +extern struct papsiz *papsizes ; +extern Boolean secure ; +extern integer hpapersize, vpapersize ; +extern int landscape ; +/* + * To maintain a list of document fonts, we use the following + * pointer. + */ +struct header_list *ps_fonts_used ; +/* + * Our hash routine. + */ +int +hash P1C(char *, s) +{ + int h = 12 ; + + while (*s != 0) + h = (h + h + *s++) % RESHASHPRIME ; + return(h) ; +} +/* + * Reverse the hash chains. + */ +void +revpslists P1H(void) { + register int i ; + for (i=0; i<RESHASHPRIME; i++) + reshash[i] = (struct resfont *)revlist(reshash[i]) ; +} +/* + * cleanres() marks all resident fonts as not being yet sent, except + * those marked with 2 meaning they were downloaded as part of the + * main prolog (not section prolog). + */ +void +cleanres P1H(void) { + register int i ; + register struct resfont *p ; + for (i=0; i<RESHASHPRIME; i++) + for (p=reshash[i]; p; p=p->next) + if (p->sent == 1) + p->sent = 0 ; +} +/* + * The routine that looks up a font name. + */ +struct resfont * +lookup P1C(char *, name) +{ + struct resfont *p ; + + for (p=reshash[hash(name)]; p!=NULL; p=p->next) + if (strcmp(p->Keyname, name)==0) + return(p) ; + return(NULL) ; +} + +struct resfont * +findPSname P1C(char *, name) +{ + register int i ; + register struct resfont *p ; + for (i=0; i<RESHASHPRIME; i++) + for (p=reshash[i]; p; p=p->next) { + if (strcmp(p->PSname, name)==0) + return p; + } + return NULL; +} + +/* + * This routine adds an entry. + */ +void +add_entry P6C(char *, TeXname, char *, PSname, char *, Fontfile, + char *, Vectfile, char *, specinfo, char *, downloadinfo) +{ + struct resfont *p ; + int h ; + if (PSname == NULL) + PSname = TeXname ; + p = (struct resfont *)mymalloc((integer)sizeof(struct resfont)) ; + p->Keyname = TeXname ; + p->PSname = PSname ; + p->Fontfile = Fontfile; + p->Vectfile = Vectfile; + p->TeXname = TeXname ; + p->specialinstructions = specinfo ; + if (downloadinfo && *downloadinfo) + p->downloadheader = downloadinfo ; + else + p->downloadheader = 0 ; + h = hash(TeXname) ; + p->next = reshash[h] ; + p->sent = 0 ; + reshash[h] = p ; +} +/* + * Now our residentfont routine. Returns the number of characters in + * this font, based on the TFM file. + */ +extern char *infont ; +int +residentfont P1C(register fontdesctype *, curfnt) +{ + register shalfword i ; + struct resfont *p ; + +/* + * First we determine if we can find this font in the resident list. + */ + if (*curfnt->area) + return 0 ; /* resident fonts never have a nonstandard font area */ + if ((p=lookup(curfnt->name))==NULL) + return 0 ; +/* + * This is not yet the correct way to do things, but it is useful as it + * is so we leave it in. The problem: if resident Times-Roman is + * re-encoded, then it will be downloaded as bitmaps; this is not + * right. The solution will be to introduce two types of `<' + * directives, one that downloads fonts and one that downloads + * short headers that are innocuous. + */ + if (p->Fontfile && downloadpspk) { +#ifdef DEBUG + if (dd(D_FONTS)) + (void)fprintf(stderr,"Using PK font %s for <%s>.\n", + curfnt->name, p->PSname) ; +#endif /* DEBUG */ + return 0 ; + } +/* + * We clear out some pointers: + */ +#ifdef DEBUG + if (dd(D_FONTS)) + (void)fprintf(stderr,"Font %s <%s> is resident.\n", + curfnt->name, p->PSname) ; +#endif /* DEBUG */ + curfnt->resfont = p ; + curfnt->name = p->TeXname ; + for (i=0; i<256; i++) { + curfnt->chardesc[i].TFMwidth = 0 ; + curfnt->chardesc[i].packptr = NULL ; + curfnt->chardesc[i].pixelwidth = 0 ; + curfnt->chardesc[i].flags = 0 ; + curfnt->chardesc[i].flags2 = 0 ; + } + add_name(p->PSname, &ps_fonts_used) ; +/* + * We include the font here. But we only should need to include the + * font if we have a stupid spooler; smart spoolers should be able + * to supply it automatically. + */ + if (p->downloadheader) { + char *cp = p->downloadheader ; + char *q ; + + infont = p->PSname ; + while (1) { + q = cp ; + while (*cp && *cp != ' ') + cp++ ; + if (*cp) { + *cp = 0 ; + add_header(q) ; + *cp++ = ' ' ; + } else { +/* if (strstr(q,".pfa")||strstr(q,".pfb")|| + strstr(q,".PFA")||strstr(q,".PFB")) + break ; + else */ { + add_header(q) ; + break; + } + } + infont = 0 ; + } + infont = 0 ; + } + i = tfmload(curfnt) ; + if (i < 0) + i = 1 ; + usesPSfonts = 1 ; + return(i) ; +} +#define INLINE_SIZE (2000) +static char was_inline[INLINE_SIZE] ; +static unsigned c_lineno; +void +bad_config P1C(char *, err) +{ + fprintf (stderr, "%s:%d:", realnameoffile, c_lineno); + error (err); + fprintf(stderr, " (%s)\n", was_inline) ; +} + +#ifndef KPATHSEA +/* + * Get environment variables! These override entries in ./config.h. + * We substitute everything of the form ::, ^: or :$ with default, + * so a user can easily build on to the existing paths. + */ +static char *getpath P2C(char *, who, char *, what) +{ + if (who) { + register char *pp, *qq ; + int lastsep = 1 ; + + for (pp=nextstring, qq=who; *qq;) { + if (*qq == PATHSEP) { + if (lastsep) { + strcpy(pp, what) ; + pp = pp + strlen(pp) ; + } + lastsep = 1 ; + } else + lastsep = 0 ; + *pp++ = *qq++ ; + } + if (lastsep) { + strcpy(pp, what) ; + pp = pp + strlen(pp) ; + } + *pp = 0 ; + qq = nextstring ; + nextstring = pp + 1 ; + return qq ; + } else + return what ; +} +#endif +/* + * We use this function so we can support strings delimited by + * double quotes with spaces in them. We also accept strings + * with spaces in them, but kill off any spaces at the end. + */ +char *configstring P2C(char *, s, int, nullok) +{ + char tstr[INLINE_SIZE] ; + char *p = tstr ; + + while (*s && *s <= ' ') + s++ ; + if (*s == '"') { + s++ ; + while (*s != 10 && *s != 0 && *s != '"' && p < tstr+290) + *p++ = *s++ ; + } else { + while (*s && p < tstr+290) + *p++ = *s++ ; + while (*(p-1) <= ' ' && p > tstr) + p-- ; + } + *p = 0 ; + if (p == tstr && ! nullok) + bad_config("bad string") ; + return newstring(tstr) ; +} +#ifdef KPATHSEA +/* We use this in `getdefaults' to modify the kpathsea structure for the + paths we read. See kpathsea/tex-file.[ch]. */ +#define SET_CLIENT_PATH(filefmt, val) \ + kpse_format_info[filefmt].client_path = xstrdup (val) +#endif +/* + * Now we have the getdefaults routine. + */ +char *psmapfile = PSMAPFILE ; +Boolean +getdefaults P1C(char *, s) +{ + FILE *deffile ; + char PSname[INLINE_SIZE] ; + register char *p ; + integer hsiz, vsiz ; +#ifndef KPATHSEA + char *d = configpath ; + int i, j ; +#endif + int canaddtopaper = 0 ; + + if (printer == NULL) { + if (s) { + strcpy(PSname, s) ; + } else { +#ifdef KPATHSEA + char *dvipsrc = kpse_var_value ("DVIPSRC"); +#ifdef WIN32 + if (dvipsrc && *dvipsrc) { + /* $DVIPSRC was set by user */ + strcpy(PSname, dvipsrc); + } + else + /* No env var, looking into some kind of standard path. */ + if (SearchPath(".;%HOME%;c:\\", ".dvipsrc", NULL, + INLINE_SIZE, PSname, + &dvipsrc) == 0) { + /* search failed, we must put something into PSname. */ + dvipsrc = kpse_var_expand(DVIPSRC); + if (dvipsrc) { + strcpy(PSname, dvipsrc); + free(dvipsrc); + } + /* Else SearchPath has filled PSname with something */ + } + /* remove any redundant path separators. Many configurations + can show up: c:\/.dvipsrc and so on ... */ + { + char *p, *q; + for (p = q = PSname; *p && (p - PSname < INLINE_SIZE) ; + p++, q++) { + if (IS_DIR_SEP(*p)) { + *q = DIR_SEP; p++; q++; + while (*p && IS_DIR_SEP(*p)) p++; + } + *q = *p; + } + *q = '\0'; + } +#else + if(!dvipsrc) dvipsrc = kpse_var_expand(DVIPSRC) ; + strcpy(PSname, dvipsrc ? dvipsrc : "~/.dvipsrc") ; + if(dvipsrc) free(dvipsrc) ; +#endif /* WIN32 */ + +#else /* ! KPATHSEA */ +#ifndef VMCMS /* IBM: VM/CMS - don't have home directory on VMCMS */ +#ifndef MVSXA + d = "~" ; +#endif +#endif /* IBM: VM/CMS */ + strcpy(PSname, DVIPSRC) ; +#endif /* KPATHSEA */ + } + } else { +#if defined(MSDOS) || defined(OS2) + strcpy(PSname, printer) ; + strcat(PSname, ".cfg") ; +#else + strcpy(PSname, "config.") ; + strcat(PSname, printer) ; +#endif + } +#ifdef KPATHSEA + if ((deffile=search(configpath,PSname,READ))!=NULL) { +#else + if ((deffile=search(d,PSname,READ))!=NULL) { +#endif +#ifdef DEBUG + if (dd (D_CONFIG)) { + fprintf (stderr, "Reading dvips config file `%s':\n", realnameoffile); + } +#endif + c_lineno = 0; + while (fgets(was_inline, INLINE_SIZE, deffile)!=NULL) { + c_lineno++; +#ifdef DEBUG + if (dd (D_CONFIG)) { + fprintf (stderr, "%s:%d:%s", realnameoffile, c_lineno, was_inline); + } +#endif +/* + * We need to get rid of the newline. + */ + for (p=was_inline; *p; p++) ; + while (p > was_inline && (*(p-1) == '\n' || *(p-1) == '\r')) { + *--p = '\0' ; + } + if (was_inline[0] != '@') + canaddtopaper = 0 ; + switch (was_inline[0]) { +/* + * Handling paper size information: + * + * If line is empty, then we clear out the paper size information + * we have so far. + * + * If it is `@+', then we add to the current paper size info. + * + * If it is `name hsize vsize', then we start a new definition. + */ +case '@' : + p = was_inline + 1 ; + while (*p && *p <= ' ') p++ ; + if (*p == 0) { + papsizes = 0 ; /* throw away memory */ + } else if (*p == '+') { + if (canaddtopaper == 0) + error( + " @+ in config files must immediately following a @ lines") ; + else { + *(nextstring-1) = '\n' ;/* IBM: VM/CMS - changed 10 to "\n" */ + p++ ; + while (*p && *p == ' ') p++ ; + strcpy(nextstring, p) ; + nextstring += strlen(p) + 1 ; + } + } else { + struct papsiz *ps ; + + ps = (struct papsiz *)mymalloc((integer)sizeof(struct papsiz)) ; + ps->next = papsizes ; + papsizes = ps ; + ps->name = p ; + while (*p && *p > ' ') + p++ ; + *p++ = 0 ; + ps->name = newstring(ps->name) ; + while (*p && *p <= ' ') p++ ; + handlepapersize(p, &hsiz, &vsiz) ; + ps->xsize = hsiz ; + ps->ysize = vsiz ; + ps->specdat = nextstring++ ; + *(ps->specdat) = 0 ; + canaddtopaper = 1 ; + } + break ; +case 'a' : + dopprescan = (was_inline[1] != '0') ; + break ; +case 'b': +#ifdef SHORTINT + if (sscanf(was_inline+1, "%ld", &pagecopies) != 1) + bad_config("missing pagecopies to b") ; +#else + if (sscanf(was_inline+1, "%d", &pagecopies) != 1) + bad_config("missing pagecopies to b") ; +#endif + if (pagecopies < 1 || pagecopies > 1000) + bad_config("pagecopies not between 1 and 1000") ; + break ; +case 'm' : +#ifdef SHORTINT + if (sscanf(was_inline+1, "%ld", &swmem) != 1) + bad_config("missing swmem to m") ; +#else /* ~SHORTINT */ + if (sscanf(was_inline+1, "%d", &swmem) != 1) + bad_config("missing swmem to m") ; +#endif /* ~SHORTINT */ + swmem += fontmem ; /* grab headers we've seen already */ + break ; +case 'M' : + /* If the user specified a -mode, don't replace it. */ + if (!mfmode_option) + mfmode = configstring(was_inline+1, 0) ; + mflandmode = 0 ; + { + char *pp ; + for (pp=mfmode; pp && *pp>' '; pp++) ; + if (pp && *pp == ' ') { + *pp++ = 0 ; + while (*pp && *pp <= ' ') + pp++ ; + if (*pp) + mflandmode = pp ; + } + } + break ; +case 'o' : + if (!oname_option) { + struct stat st_buf; + oname = configstring(was_inline+1, 1) ; + if ((*oname && oname[strlen(oname)-1] == ':') + || (stat(oname, &st_buf) == 0 && S_ISCHR(st_buf.st_mode))) { + sendcontrolD = 1 ; /* if we send to a device, *we* are spooler */ +#if defined(MSDOS) || defined(OS2) + oname[strlen(oname)-1] = 0 ; +#endif + } + } + break ; +case 'F' : + sendcontrolD = (was_inline[1] != '0') ; + break ; +case 'O' : + p = was_inline + 1 ; + handlepapersize(p, &hoff, &voff) ; + break ; +#ifdef FONTLIB +case 'L' : + { + char tempname[INLINE_SIZE] ; + extern char *fliparse() ; + if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config("missing arg to L") ; + else { + flipath = getpath(fliparse(PSname,tempname), flipath); + fliname = newstring(tempname) ; + } + } + break ; +#endif +case 'T' : + if (sscanf(was_inline+1, "%s", PSname) != 1) + bad_config("missing arg to T") ; + else +#ifdef KPATHSEA + SET_CLIENT_PATH (kpse_tfm_format, PSname); +#else + tfmpath = getpath(PSname, tfmpath) ; +#endif + break ; +case 'P' : + if (sscanf(was_inline+1, "%s", PSname) != 1) bad_config("missing arg to P") ; + else +#ifdef KPATHSEA + SET_CLIENT_PATH (kpse_pk_format, PSname); +#else + pkpath = getpath(PSname, pkpath) ; +#endif + break ; +case 'p' : + p = was_inline + 1 ; + while (*p && *p <= ' ') + p++ ; + if (*p == '+') { + if (sscanf(p+1, "%s", PSname) != 1) + bad_config("missing arg to p") ; + getpsinfo(PSname) ; + } else { + psmapfile = configstring(was_inline+1, 0) ; + } + break ; +case 'v' : case 'V' : + if (sscanf(was_inline+1, "%s", PSname) != 1) + bad_config("missing arg to V") ; + else +#ifdef KPATHSEA + SET_CLIENT_PATH (kpse_vf_format, PSname); +#else + vfpath = getpath(PSname, vfpath) ; +#endif + break ; +case 'S' : + if (sscanf(was_inline+1, "%s", PSname) != 1) + bad_config("missing arg to S") ; + else +#ifdef KPATHSEA + SET_CLIENT_PATH (kpse_pict_format, PSname); +#else + figpath = getpath(PSname, figpath) ; +#endif + break ; +case 's': + safetyenclose = 1 ; + break ; +case 'H' : + if (sscanf(was_inline+1, "%s", PSname) != 1) + bad_config("missing arg to H") ; + else +#ifdef KPATHSEA + SET_CLIENT_PATH (headerpath, PSname); +#else + headerpath = getpath(PSname, headerpath) ; +#endif + break ; +case '%': case ' ' : case '*' : case '#' : case ';' : +case '=' : case 0 : case '\n' : + break ; +case 'r' : + reverse = (was_inline[1] != '0') ; + break ; +/* + * This case is for last resort font scaling; I hate this, but enough + * people have in no uncertain terms demanded it that I'll go ahead and + * add it. + * + * This line must have numbers on it, resolutions, to search for the + * font as a last resort, and then the font will be scaled. These + * resolutions should be in increasing order. + * + * For most machines, just `300' is sufficient here; on the NeXT, + * `300 400' may be more appropriate. + */ +case 'R': +#ifndef KPATHSEA + i = 0 ; + p = was_inline + 1 ; + while (*p) { + while (*p && *p <= ' ') + p++ ; + if ('0' <= *p && *p <= '9') { + j = 0 ; + while ('0' <= *p && *p <= '9') + j = 10 * j + (*p++ - '0') ; + if (i > 0) + if (lastresortsizes[i-1] > j) { + bad_config("last resort sizes (R) must be sorted") ; + } + lastresortsizes[i++] = j ; + } else { + if (*p == 0) + break ; + bad_config("only numbers expected on `R' line") ; + } + } + lastresortsizes[i] = 32000 ; +#else /* KPATHSEA */ + for (p = was_inline + 1; *p; p++) { + if (isblank (*p)) { + *p = ':'; + } + } + kpse_fallback_resolutions_string = xstrdup (was_inline + 1); +#endif + break ; +case 'D' : + if (sscanf(was_inline+1, "%d", &actualdpi) != 1) + bad_config("missing arg to D") ; + if (actualdpi < 10 || actualdpi > 10000) + bad_config("dpi must be between 10 and 10000") ; + vactualdpi = actualdpi; + break ; +/* + * Execute a command. This can be dangerous, but can also be very useful. + */ +case 'E' : +#ifdef SECURE + error("dvips was compiled with SECURE, which disables E in config") ; +#else + if (secure) { + error("dvips -R option used, which disables E in config") ; + break ; + } + (void)system(was_inline+1) ; +#endif + break ; +case 'K': + removecomments = (was_inline[1] != '0') ; + break ; +case 'U': + nosmallchars = (was_inline[1] != '0') ; + break ; +case 'W': + for (p=was_inline+1; *p && *p <= ' '; p++) ; + if (*p) + warningmsg = newstring(p) ; + else + warningmsg = 0 ; + break ; +case 'X' : + if (sscanf(was_inline+1, "%d", &actualdpi) != 1) + bad_config("missing numeric arg to X") ; + if (actualdpi < 10 || actualdpi > 10000) + bad_config("X arg must be between 10 and 10000") ; + break ; +case 'Y' : + if (sscanf(was_inline+1, "%d", &vactualdpi) != 1) + bad_config("missing numeric arg to Y") ; + if (vactualdpi < 10 || vactualdpi > 10000) + bad_config("Y arg must be between 10 and 10000") ; + break ; +case 'x': case 'y': + if (sscanf(was_inline+1, "%lg", &mag) != 1) + bad_config("missing arg to x or y") ; + overridemag = (was_inline[0] == 'x') ? 1 : -1 ; + break ; +case 'e' : + if (sscanf(was_inline+1, "%d", &maxdrift) != 1) + bad_config("missing arg to e") ; + if (maxdrift < 0) bad_config("bad argument to e") ; + vmaxdrift = maxdrift; + break ; +case 'z' : + if (secure_option && secure && was_inline[1] == '0') { + fprintf (stderr, + "warning: %s: z0 directive ignored since -R1 given\n", + realnameoffile); + } else { + secure = (was_inline[1] != '0') ; + } + break ; +case 'q' : case 'Q' : + quiet = (was_inline[1] != '0') ; + break ; +case 'f' : + filter = (was_inline[1] != '0') ; + if (filter) + oname = ""; + /* noenv has already been tested, so no point in setting. */ + sendcontrolD = 0; + break ; +#ifdef SHIFTLOWCHARS +case 'G': + shiftlowchars = (was_inline[1] != '0') ; + break ; +#endif +case 'h' : + if (sscanf(was_inline+1, "%s", PSname) != 1) + bad_config("missing arg to h") ; + else (void)add_header(PSname) ; + break ; +case 'i' : + if (sscanf(was_inline+1, "%d", &maxsecsize) != 1) + maxsecsize = 0 ; + sepfiles = 1 ; + break ; +case 'I': + noenv = (was_inline[1] != '0') ; + break ; +case 'N' : + disablecomments = (was_inline[1] != '0') ; + break ; +case 'Z' : + compressed = (was_inline[1] != '0') ; + break ; +case 'j': + partialdownload = (was_inline[1] != '0') ; + break ; +case 't' : + if (sscanf(was_inline+1, "%s", PSname) != 1) + bad_config("missing arg to t") ; + else { + if (strcmp(PSname, "landscape") == 0) { + if (hpapersize || vpapersize) + error( + "both landscape and papersize specified; ignoring landscape") ; + else + landscape = 1 ; + } else + paperfmt = newstring(PSname) ; + } + break ; +default: + bad_config("strange line") ; + } + } + (void)fclose(deffile) ; + } else { + if (printer) + { + char msg[1000]; + sprintf (msg, "warning: no config file for `%s'", printer); + error(msg); + return 0; + } + } + + return 1; +} + +/* +* If a character pointer is passed in, use that name; else, use the +* default (possibly set) name, psfonts.map. +*/ +void getpsinfo P1C(char *, name) +{ + FILE *deffile ; + register char *p ; + char *specinfo, *downloadinfo ; + char downbuf[500] ; + char specbuf[500] ; + int slen ; + + if (name == 0) + name = psmapfile ; + if ((deffile=search(mappath, name, READ))!=NULL) { + while (fgets(was_inline, INLINE_SIZE, deffile)!=NULL) { + p = was_inline ; + if (*p > ' ' && *p != '*' && *p != '#' && *p != ';' && *p != '%') { + char *TeXname = NULL ; + char *PSname = NULL ; + char *Fontfile = NULL; + char *Vectfile = NULL; + char *hdr_name = NULL; + boolean nopartial_p = false; + boolean encoding_p = false; + specinfo = NULL ; + downloadinfo = NULL ; + downbuf[0] = 0 ; + specbuf[0] = 0 ; + while (*p) { + encoding_p = false ; + while (*p && *p <= ' ') + p++ ; + if (*p) { + if (*p == '"') { /* PostScript instructions? */ + if (specinfo) { + strcat(specbuf, specinfo) ; + strcat(specbuf, " ") ; + } + specinfo = p + 1 ; + + } else if (*p == '<') { /* Header to download? */ + /* If had previous downloadinfo, save it. */ + if (downloadinfo) { + strcat(downbuf, downloadinfo) ; + strcat(downbuf, " ") ; + downloadinfo = NULL; + } + if (p[1] == '<') { /* << means always full download */ + p++; + nopartial_p = true; + } else if (p[1] == '[') { /* <[ means an encoding */ + p++; + encoding_p = true; + } + p++ ; + /* skip whitespace after < */ + while (*p && *p <= ' ') + p++; + + /* save start of header name */ + hdr_name = p ; + + } else if (TeXname) /* second regular word on line? */ + PSname = p ; + + else /* first regular word? */ + TeXname = p ; + + if (*p == '"') { + p++ ; /* find end of "..." word */ + while (*p != '"' && *p) + p++ ; + } else + while (*p > ' ') /* find end of anything else */ + p++ ; + if (*p) + *p++ = 0 ; + + /* If we had a header we were downloading, figure + out what to do; couldn't do this above since we + want to check the suffix. */ + if (hdr_name) { + char *suffix = find_suffix (hdr_name); + if (encoding_p || STREQ (suffix, "enc")) { + /* (SPQR) if it is a reencoding, pass on to + FontPart, and download as usual */ + Vectfile = downloadinfo = hdr_name; + } else if (nopartial_p) { + downloadinfo = hdr_name ; + } else if (FILESTRCASEEQ (suffix, "pfa") + || FILESTRCASEEQ (suffix, "pfb") + || STREQ (suffix, "PFA") + || STREQ (suffix, "PFB")) { + Fontfile = hdr_name; + } else { + downloadinfo = hdr_name; + } + } + } + } + if (specinfo) + strcat(specbuf, specinfo) ; + if (downloadinfo) + strcat(downbuf, downloadinfo) ; + slen = strlen(downbuf) - 1; + if (downbuf[slen] == ' ') { + downbuf[slen] = 0; + } + if (TeXname) { + TeXname = newstring(TeXname) ; + PSname = newstring(PSname) ; + Fontfile = newstring(Fontfile); + Vectfile = newstring(Vectfile); + specinfo = newstring(specbuf) ; + downloadinfo = newstring(downbuf) ; + add_entry(TeXname, PSname, Fontfile, Vectfile, + specinfo, downloadinfo) ; + } + } + } + (void)fclose(deffile) ; + } + checkstrings() ; +} +#ifndef KPATHSEA +/* + * Get environment variables! These override entries in ./config.h. + * We substitute everything of the form ::, ^: or :$ with default, + * so a user can easily build on to the existing paths. + */ +static char *getenvup P2C(char *, who, char *, what) +{ + return getpath(getenv(who), what) ; +} +#endif +#if !defined(KPATHSEA) && defined(SEARCH_SUBDIRECTORIES) +static char *concat3(); +#endif +void checkenv P1C(int, which) +{ +#ifndef KPATHSEA + if (which) { + tfmpath = getenvup(FONTPATH, tfmpath) ; + vfpath = getenvup("VFFONTS", vfpath) ; + pictpath = getenvup("TEXPICTS", pictpath) ; + figpath = getenvup("TEXINPUTS", figpath) ; + headerpath = getenvup("DVIPSHEADERS", headerpath) ; + if (getenv("TEXPKS")) + pkpath = getenvup("TEXPKS", pkpath) ; + else if (getenv("TEXPACKED")) + pkpath = getenvup("TEXPACKED", pkpath) ; + else if (getenv("PKFONTS")) + pkpath = getenvup("PKFONTS", pkpath) ; +#ifdef SEARCH_SUBDIRECTORIES + else if (getenv(FONTPATH)) + pkpath = getenvup(FONTPATH, pkpath) ; + if (getenv ("TEXFONTS_SUBDIR")) + fontsubdirpath = getenvup ("TEXFONTS_SUBDIR", fontsubdirpath); + { + char pathsep[2] ; + char *do_subdir_path(); + char *dirs = do_subdir_path (fontsubdirpath); + /* If the paths were in dynamic storage before, that memory is + wasted now. */ + pathsep[0] = PATHSEP ; + pathsep[1] = '\0' ; + tfmpath = concat3 (tfmpath, pathsep, dirs); + pkpath = concat3 (pkpath, pathsep, dirs); + } +#endif + } else + configpath = getenvup("TEXCONFIG", configpath) ; +#endif +} + +#if !defined(KPATHSEA) && defined(SEARCH_SUBDIRECTORIES) + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> + +#ifdef SYSV +#include <dirent.h> +typedef struct dirent *directory_entry_type; +#else +#include <sys/dir.h> +typedef struct direct *directory_entry_type; +#endif + +/* Declare the routine to get the current working directory. */ + +#ifndef HAVE_GETCWD +extern char *getwd (); +#define getcwd(b, len) ((b) ? getwd (b) : getwd (xmalloc (len))) +#else +#ifdef ANSI +extern char *getcwd (char *, int); +#else +extern char *getcwd (); +#endif /* not ANSI */ +#endif /* not HAVE_GETWD */ + +#if defined(SYSV) || defined(VMS) || defined(MSDOS) || defined(OS2) || defined(ATARIST) +#define MAXPATHLEN (256) +#else /* ~SYSV */ +#include <sys/param.h> /* for MAXPATHLEN */ +#endif + +extern void exit() ; +extern int chdir() ; + +/* Memory operations: variants of malloc(3) and realloc(3) that just + give up the ghost when they fail. */ + +char * +xmalloc P1C(unsigned, size) +{ + char *mem = malloc (size); + + if (mem == NULL) + { + fprintf (stderr, "! Cannot allocate %u bytes.\n", size); + exit (10); + } + + return mem; +} + + +char * +xrealloc P2C(char *, ptr, unsigned, size) +{ + char *mem = realloc (ptr, size); + + if (mem == NULL) + { + fprintf (stderr, "! Cannot reallocate %u bytes at %x.\n", size, (int)ptr); + exit (10); + } + + return mem; +} + + +/* Return, in NAME, the next component of PATH, i.e., the characters up + to the next PATHSEP. */ + +static void +next_component P2C(char *, name, char **, path) +{ + unsigned count = 0; + + while (**path != 0 && **path != PATHSEP) + { + name[count++] = **path; + (*path)++; /* Move further along, even between calls. */ + } + + name[count] = 0; + if (**path == PATHSEP) + (*path)++; /* Move past the delimiter. */ +} + + +#ifndef _POSIX_SOURCE +#ifndef S_ISDIR +#define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR) +#endif +#endif + +/* Return true if FN is a directory or a symlink to a directory, + false if not. */ + +int +is_dir P1C(char *, fn) +{ + struct stat stats; + + return stat (fn, &stats) == 0 && S_ISDIR (stats.st_mode); +} + + +static char * +concat3 P3C(char *, s1, char *, s2, char *, s3) +{ + char *r = xmalloc (strlen (s1) + strlen (s2) + strlen (s3) + 1); + strcpy (r, s1); + strcat (r, s2); + strcat (r, s3); + return r; +} + + +/* DIR_LIST is the default list of directories (colon-separated) to + search. We want to add all the subdirectories directly below each of + the directories in the path. + + We return the list of directories found. */ + +char * +do_subdir_path P1C(char *, dir_list) +{ + char *cwd; + unsigned len; + char *result = xmalloc ((unsigned)1); + char *temp = dir_list; + char dirsep[2] ; + + dirsep[0] = DIRSEP ; + dirsep[1] = '\0' ; + + /* Make a copy in writable memory. */ + dir_list = xmalloc (strlen (temp) + 1); + strcpy (dir_list, temp); + + *result = 0; + + /* Unfortunately, we can't look in the environment for the current + directory, because if we are running under a program (let's say + Emacs), the PWD variable might have been set by Emacs' parent + to the current directory at the time Emacs was invoked. This + is not necessarily the same directory the user expects to be + in. So, we must always call getcwd(3) or getwd(3), even though + they are slow and prone to hang in networked installations. */ + cwd = getcwd (NULL, MAXPATHLEN + 2); + if (cwd == NULL) + { + perror ("getcwd"); + exit (errno); + } + + do + { + DIR *dir; + directory_entry_type e; + char dirname[MAXPATHLEN]; + + next_component (dirname, &dir_list); + + /* All the `::'s should be gone by now, but we may as well make + sure `chdir' doesn't crash. */ + if (*dirname == 0) continue; + + /* By changing directories, we save a bunch of string + concatenations (and make the pathnames the kernel looks up + shorter). */ + if (chdir (dirname) != 0) continue; + + dir = opendir ("."); + if (dir == NULL) continue; + + while ((e = readdir (dir)) != NULL) + { + if (is_dir (e->d_name) && strcmp (e->d_name, ".") != 0 + && strcmp (e->d_name, "..") != 0) + { + char *found = concat3 (dirname, dirsep, e->d_name); + + result = xrealloc (result, strlen (result) + strlen (found) + 2); + + len = strlen (result); + if (len > 0) + { + result[len] = PATHSEP; + result[len + 1] = 0; + } + strcat (result, found); + free (found); + } + } + closedir (dir); + + /* Change back to the current directory, in case the path + contains relative directory names. */ + if (chdir (cwd) != 0) + { + perror (cwd); + exit (errno); + } + } + while (*dir_list != 0); + + return result; +} +#endif /* SEARCH_SUBDIRECTORIES */ |