/* External procedures for use with dvidoc. Adapted from those used in dvip. Written by H. Trickey, 9/3/83. Implement the following procedures (as declared in Pascal) procedure opendvifile; function getbyte: integer; function signedbyte: integer; function gettwobytes: integer; function signedpair: integer; function getthreebytes: integer; function signedtrio: integer; function signedquad: integer; function curpos(var f:bytefile):integer; procedure setpos(var f:bytefile;n:integer); procedure setpaths; function testaccess(accessmode:integer; filepath:integer):boolean; Declaration for eofdvifile changed from int to char to match Pascal boolean, otherwise fails on 68000's (byte ordering problem). Ken Yap, Feb 1986 */ #include #include #include "texpaths.h" static FILE *dvif; extern char eofdvifile; /* needs to be set true when this happens */ extern int curloc; /* needs to be incremented by getbyte, signedbyte */ #define namelength 100 /* should agree with dvitype.ch */ extern char curname[],realnameoffile[]; /* these have size namelength */ /* open the dvifile, using the name in realnameoffile */ opendvifile() { register int i; for (i = namelength - 1; i >= 0; --i) if (realnameoffile[i] == ' ') realnameoffile[i] = '\0'; else break; if (!(dvif=fopen(realnameoffile,"r"))) eofdvifile = 1; else eofdvifile = 0; } /* return unsigned version of next byte in dvifile */ int getbyte() { register int c; if ((c = getc(dvif))==EOF) { eofdvifile = 1; return(0); } curloc++; return(c); } /* return signed version of next byte in dvifile */ int signedbyte() { register int c; if ((c = getc(dvif))==EOF) { eofdvifile = 1; return(0); } curloc++; if (c>127) return(c-256); return(c); } /* return unsigned value of next two bytes (high order first) */ int gettwobytes() { register int a,b; a = getc(dvif); eofdvifile = ((b = getc(dvif))==EOF); curloc += 2; return((a << 8) | b); } /* return signed value of next two bytes (high order first) */ int signedpair() { register int a,b; if ( (a = getc(dvif)) > 127) a -= 256; /* sign extend */ eofdvifile = ((b = getc(dvif))==EOF); curloc += 2; return((a << 8) | b); } /* return unsigned value of next three bytes */ int getthreebytes() { register int a,b,c; a = getc(dvif); b = getc(dvif); eofdvifile = ((c = getc(dvif))==EOF); curloc +=3; return((a << 16) | (b << 8) | c); } /* return signed value of next three bytes */ int signedtrio() { register int a,b,c; if ( (a = getc(dvif)) > 127) a -= 256; b = getc(dvif); eofdvifile = ((c = getc(dvif))==EOF); curloc +=3; return((a << 16) | (b << 8) | c); } /* return value of next four bytes */ int signedquad() { register int a,b,c,d; a = getc(dvif); b = getc(dvif); c = getc(dvif); eofdvifile = ((d = getc(dvif))==EOF); curloc += 4; return((a << 24) | (b << 16) | (c << 8) | d); } /* seek to byte n of file f: actually, assume f is for dvifile */ setpos(f,n) int f; /* not really, but we ignore it */ int n; { if (n>=0) { fseek(dvif,(long) n,0); eofdvifile = 0; } else { fseek(dvif, (long) n, 2); eofdvifile = 1; } } /* return current byte offset in file f (again, assume dvifile) */ int curpos(f) int f; { return((int) ftell(dvif)); } char *fontpath; char *getenv(); /* * setpaths is called to set up the pointer fontpath * as follows: if the user's environment has a value for TEXFONTS * then use it; otherwise, use defaultfontpath. */ setpaths() { register char *envpath; if ((envpath = getenv("TEXFONTS")) != NULL) fontpath = envpath; else fontpath = defaultfontpath; } /* * testaccess(amode,filepath) * * Test whether or not the file whose name is in the global curname * can be opened for reading (if mode=READACCESS) * or writing (if mode=WRITEACCESS). * * The filepath argument is one of the ...FILEPATH constants defined below. * If the filename given in curname does not begin with '/', we try * prepending all the ':'-separated areanames in the appropriate path to the * filename until access can be made, if it ever can. * * The realnameoffile global array will contain the name that yielded an * access success. */ #define READACCESS 4 #define WRITEACCESS 2 #define NOFILEPATH 0 #define FONTFILEPATH 3 typedef enum {FALSE, TRUE} bool; bool testaccess(amode,filepath) int amode,filepath; { register bool ok; register char *p; char *curpathplace; int f; switch(filepath) { case NOFILEPATH: curpathplace = NULL; break; case FONTFILEPATH: curpathplace = fontpath; break; } if (curname[0]=='/') /* file name has absolute path */ curpathplace = NULL; do { packrealnameoffile(&curpathplace); if (amode==READACCESS) /* use system call "access" to see if we could read it */ if (access(realnameoffile,READACCESS)==0) ok = TRUE; else ok = FALSE; else { /* WRITEACCESS: use creat to see if we could create it, but close the file again if we're OK, to let pc open it for real */ f = creat(realnameoffile,0666); if (f>=0) ok = TRUE; else ok = FALSE; if (ok) close(f); } } while (!ok && curpathplace != NULL); if (ok) { /* pad realnameoffile with blanks, as Pascal wants */ for (p = realnameoffile; *p != '\0'; p++) /* nothing: find end of string */ ; while (p < &(realnameoffile[namelength])) *p++ = ' '; } return (ok); } /* * packrealnameoffile(cpp) makes realnameoffile contain the directory at *cpp, * followed by '/', followed by the characters in curname up until the * first blank there, and finally a '\0'. The cpp pointer is left pointing * at the next directory in the path. * But: if *cpp == NULL, then we are supposed to use curname as is. */ packrealnameoffile(cpp) char **cpp; { register char *p,*realname; realname = realnameoffile; if ((p = *cpp)!=NULL) { while ((*p != ':') && (*p != '\0')) { *realname++ = *p++; if (realname == &(realnameoffile[namelength-1])) break; } if (*p == '\0') *cpp = NULL; /* at end of path now */ else *cpp = p+1; /* else get past ':' */ *realname++ = '/'; /* separate the area from the name to follow */ } /* now append curname to realname... */ p = curname; while (*p != ' ' && *p != '\0') { if (realname >= &(realnameoffile[namelength-1])) { fprintf(stderr,"! Full file name is too long\n"); break; } *realname++ = *p++; } *realname = '\0'; }