/* * External procedures for all Metafontware programs. * * Pierre A. MacKay * The various routines consolidated into this package * were produced over the past six years, by a number * of contributors. Howard Trickey and Tim Morgan * are the principal authors. */ #include "mfware.h" #ifdef _POSIX_SOURCE #include #else #ifdef SYSV #include extern int sprintf(); #else #include extern char *sprintf(); #endif #endif #define TRUE 1 #define FALSE 0 integer argc; char *texfontpath; char *texinputpath; char *gffontpath; char *pkfontpath; extern char *getenv(); static char **gargv; argv(n, buf) int n; char buf[]; { (void) strcpy(buf+1, gargv[n]); (void) strcat(buf+1, " "); } main(ac, av) char *av[]; { argc = ac; gargv = av; main_body(); exit(0); } /* Same routine as index() aka strchr() */ #ifndef SYSV char *char_index(cp, c) char *cp, c; { while (*cp != c && *cp) ++cp; if (*cp) return(cp); return(0); } #else /* not SYSV */ #define char_index strchr #endif /* Open a file; don't return if error */ FILE *openf(name, mode) char *name, *mode; { FILE *result; char *cp; /* Sometimes the filenames will have a trailing ' ' */ cp = char_index(name, ' '); if (cp) *cp = '\0'; result = fopen(name, mode); if (result) return(result); perror(name); exit(1); /*NOTREACHED*/ } /* Print real number r in format n:m. */ printreal(r, n, m) double r; int n,m; { char fmt[50]; (void) sprintf(fmt, "%%%d.%df", n, m); (void) printf(fmt, r); } /* Print string s in format :n. */ printstring(s, n) char *s; int n; { fwrite (s+1, 1, n, stdout); } /* Return true on end of line or eof of file, else false */ eoln(f) FILE *f; { register int c; if (feof(f)) return(1); c = getc(f); if (c != EOF) (void) ungetc(c, f); return (c == '\n' || c == EOF); } #ifdef ANSI integer zround(double f) #else integer zround(f) double f; #endif { if (f >= 0.0) return(f + 0.5); return(f - 0.5); } /* * Return true if we're at the end of the file, else false. */ testeof(file) FILE *file; { int ch; if (feof(file)) return(true); if ((ch = getc(file)) == EOF) return(true); (void) ungetc(ch,file); /* yuck */ return(false); } /* Read an integer in from file f; read past the subsequent end of line */ #ifdef ANSI integer inputint(FILE *f) #else integer inputint(f) FILE *f; #endif { char buffer[20]; if (fgets(buffer, sizeof(buffer), f)) return(atoi(buffer)); return(0); } zinput_3ints(a,b,c) integer *a, *b, *c; { while (scanf("%ld %ld %ld\n", a, b, c) != 3) (void) fprintf(stderr, "Please enter three integers\n"); } /* * setpaths is called to set up the pointer fontpath * as follows: if the user's environment has a value for * one of: TEXFONTS, PKFONTS, GFFONTS * then use it; otherwise, use defaultfontpath. * TEXFONTS is the traditional place for TFM files, and * used to be used indiscriminately for raster files as well. * It now seems desirable to separate these, although not all sites do. */ setpaths() { register char *envpath; if ((envpath = getenv("TEXFONTS")) != NULL) texfontpath = envpath; else texfontpath = TEXFONTS; if ((envpath = getenv("TEXINPUTS")) != NULL) texinputpath = envpath; else texinputpath = TEXINPUTS; if ((envpath = getenv("GFFONTS")) != NULL) gffontpath = envpath; else gffontpath = TEXFONTS; if ((envpath = getenv("PKFONTS")) != NULL) pkfontpath = envpath; else pkfontpath = TEXFONTS; } extern char curname[],realnameoffile[]; /* should have length FILENAMESIZE as given in site.h */ /* * 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 TEXFONTFILEPATH 3 #define TEXINPUTFILEPATH 2 #define GFFONTFILEPATH 4 #define PKFONTFILEPATH 5 /* * 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. */ static packrealnameoffile(cpp) char **cpp; { register char *p,*realname; realname = realnameoffile; if ((p = *cpp)!=NULL) { while ((*p != ':') && (*p != '\0')) { *realname++ = *p++; if (realname == &(realnameoffile[FILENAMESIZE-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 + 1; while (*p != ' ') { if (realname >= &(realnameoffile[FILENAMESIZE-1])) { (void) fprintf(stderr,"! Full file name `%s' is too long.\n", realname); break; } *realname++ = *p++; } *realname = '\0'; } testaccess(amode,filepath) int amode,filepath; { register boolean ok; register char *p; char *curpathplace; int f; switch(filepath) { case NOFILEPATH: curpathplace = NULL; break; case TEXFONTFILEPATH: curpathplace = texfontpath; break; case TEXINPUTFILEPATH: curpathplace = texinputpath; break; case GFFONTFILEPATH: curpathplace = gffontpath; break; case PKFONTFILEPATH: curpathplace = pkfontpath; break; } if (curname[1]=='/') /* 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); ok = (f >= 0); if (ok) (void) 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[FILENAMESIZE])) *p++ = ' '; } return (ok); }