DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T f

⟦5659775da⟧ TextFile

    Length: 8953 (0x22f9)
    Types: TextFile
    Names: »findfile.c«

Derivation

└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
    └─⟦this⟧ »./DVIware/crt-viewers/others/findfile.c« 

TextFile

/*
 * dvipage: DVI Previewer Program for Suns
 *
 * Neil Hunt (hunt@spar.slb.com)
 *
 * Copyright (c) 1988 Schlumberger Technologies, Inc 1988.
 * Anyone can use this software in any manner they choose,
 * including modification and redistribution, provided they make
 * no charge for it, and these conditions remain unchanged.
 *
 * This program is distributed as is, with all faults (if any), and
 * without any warranty. No author or distributor accepts responsibility
 * to anyone for the consequences of using it, or for whether it serves any
 * particular purpose at all, or any other reason.
 *
 * $Log:	findfile.c,v $
 * Revision 1.1  88/11/28  18:40:44  hunt
 * Initial revision
 * 
 * Based upon `mitdrivers/findfile.c'
 * Copyright 1985 Massachusetts Institute of Technology
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/file.h>
#include <sys/param.h>		/* For MAXPATHLEN */
#include <suntool/sunview.h>
#include "dvipage.h"

forward bool	find_file_in_path();
forward bool	find_best_file_in_path();
forward bool	scandir();
forward bool	scanpdir();
forward int	strdiff();


/*
 * find_file:
 *	Seaches for a font file in various places.
 *	dirpath is a colon separated list of possible pathnames.
 *	Returns TRUE if a usable file was found.
 */

bool find_font_file(dir_path, fontptr)
char *dir_path;
struct font_entry *fontptr;
{
	int min_df, min_dp, min_dm;

	if(verbose & DEBUG_FONTS)
		fprintf(stderr, "find_font_file(%s .%dgf or .%dpxl)\n",
		  fontptr->n, fontptr->font_gf_mag, fontptr->font_pxl_mag);

	/*
	 * Search for exact match.
	 */
	if(find_file_in_path(dir_path, fontptr))
		return TRUE;

	/*
	 * Search for nearest match.
	 */
	min_df = min_dp = min_dm = MAXINT;
	if(find_best_file_in_path(dir_path, fontptr,
	  &min_df, &min_dp, &min_dm))
	{
		message("Substituted font %s for %s.%d.",
		  fontptr->name, fontptr->n, fontptr->type == TYPE_PXL ?
		  fontptr->font_pxl_mag : fontptr->font_gf_mag);
		return TRUE;
	}

	return FALSE;
}

/*
 * find_file_in_path:
 *	Searches path for a font file.
 *	Returns TRUE if a suitable match has been found.
 */

bool
find_file_in_path(dirpath, fontptr)
char *dirpath;
struct font_entry *fontptr;
{
	char *p;
	char dir[MAXPATHLEN];

	while(*dirpath)
	{
		/*
		 * Copy first/next path prefix to dir[].
		 * Skip over the ':'.
		 */
		for(p = dir; *dirpath; )
		{
			if(*dirpath == ':' || *dirpath == ';')
			{
				dirpath++;
				break;
			}
			else
				*p++ = *dirpath++;
		}
		*p = '\0';

		if(use_gf)
		{
			/*
			 * Try flat structure.
			 */
			sprintf(fontptr->name, "%s/%s.%dgf",
			  dir, fontptr->n, fontptr->font_gf_mag);
			if(access(fontptr->name, R_OK) == 0)
			{
				if(verbose & DEBUG_FONTS)
					fprintf(stderr, " Try %s; OK\n",
					  fontptr->name);
				fontptr->type = TYPE_GF;
				return TRUE;
			}
			else
			{
				if(verbose & DEBUG_FONTS)
					fprintf(stderr, " Try %s; No\n",
					  fontptr->name);
			}

			/*
			 * Try hierarchical structure.
			 */
			sprintf(fontptr->name, "%s/%s/%s.%dgf",
			  dir, fontptr->n, fontptr->n, fontptr->font_gf_mag);
			if(access(fontptr->name, R_OK) == 0)
			{
				if(verbose & DEBUG_FONTS)
					fprintf(stderr, " Try %s; OK\n",
					  fontptr->name);
				fontptr->type = TYPE_GF;
				return TRUE;
			}
			else
			{
				if(verbose & DEBUG_FONTS)
					fprintf(stderr, " Try %s; No\n",
					  fontptr->name);
			}
		}

		if(use_pxl)
		{
			/*
			 * Try flat structure.
			 */
			sprintf(fontptr->name, "%s/%s.%dpxl",
			  dir, fontptr->n, fontptr->font_pxl_mag);
			if(access(fontptr->name, R_OK) == 0)
			{
				if(verbose & DEBUG_FONTS)
					fprintf(stderr, " Try %s; OK\n",
					  fontptr->name);
				fontptr->type = TYPE_PXL;
				return TRUE;
			}
			else
			{
				if(verbose & DEBUG_FONTS)
					fprintf(stderr, " Try %s; No\n",
					  fontptr->name);
			}

			/*
			 * Try hierarchical structure.
			 */
			sprintf(fontptr->name, "%s/%s/%s.%dpxl",
			  dir, fontptr->n, fontptr->n, fontptr->font_pxl_mag);
			if(access(fontptr->name, R_OK) == 0)
			{
				if(verbose & DEBUG_FONTS)
					fprintf(stderr, " Try %s; OK\n",
					  fontptr->name);
				fontptr->type = TYPE_PXL;
				return TRUE;
			}
			else
			{
				if(verbose & DEBUG_FONTS)
					fprintf(stderr, " Try %s; No\n",
					  fontptr->name);
			}
		}
	}

	return FALSE;
}

/*
 * find_best_file_in_path:
 *	Finds the best match to the desired font.
 *	Returns TRUE if a suitable match is found.
 */

bool
find_best_file_in_path(dirpath, fontptr, p_min_df, p_min_dp, p_min_dm)
char *dirpath;
struct font_entry *fontptr;
int *p_min_df, *p_min_dp, *p_min_dm;
{
	register char *p;
	char dir[MAXPATHLEN];
	bool status = FALSE;

	if(verbose & DEBUG_FONTS)
		fprintf(stderr, "find_best_font_file(%s .%dgf or %dpxl)\n",
		  fontptr->n, fontptr->font_gf_mag, fontptr->font_pxl_mag);

	/*
	 * Scan over directories in dirpath.
	 */
	while(*dirpath)
	{
		/*
		 * Copy first/next path prefix to dir[].
		 * Skip over the ':'.
		 */
		for(p = dir; *dirpath != '\0'; )
		{
			if(*dirpath == ':' || *dirpath == ';')
			{
				dirpath++;
				break;
			}
			else
				*p++ = *dirpath++;
		}
		*p = '\0';

		/*
		 * Scan the directory.
		 */
		if(scanpdir(dir, fontptr, p_min_df, p_min_dp, p_min_dm))
			status = TRUE;

		/*
		 * Scan any subdirectories.
		 */
		if(scandir(dir, fontptr, p_min_df, p_min_dp, p_min_dm))
			status = TRUE;
	}

	return status;
}

/*
 * scandir:
 *	Scan directory looking for plausible names,
 *	then recurse to subdirectories for plausible point sizes.
 *	Returns TRUE if found a more plausible candidate than previous best.
 */

bool
scandir(dir, fontptr, p_min_df, p_min_dp, p_min_dm)
char *dir;
struct font_entry *fontptr;
int *p_min_df, *p_min_dp, *p_min_dm;
{
	DIR *dirstream;
	struct direct *dirrecord;
	char pdir[MAXPATHLEN];
	bool status = FALSE;

	if(verbose & DEBUG_FONTS)
		fprintf(stderr, " scandir(%s .%dgf or .%dpxl)\n",
		  fontptr->n, fontptr->font_gf_mag, fontptr->font_pxl_mag);

	if(! (dirstream = opendir(dir)))
		return FALSE;

	while(dirrecord = readdir(dirstream))
	{
		if(dirrecord->d_name[0] != '.')
			continue;

		if(strdiff(fontptr->n, dirrecord->d_name) <= *p_min_df)
		{
			sprintf(pdir, "%s/%s", dir, dirrecord->d_name);

			if(scanpdir(pdir, fontptr,
			  p_min_df, p_min_dp, p_min_dm))
				status = TRUE;
		}
	}

	closedir(dirstream);

	return status;
}

/*
 * scanpdir:
 *	Scan directory looking for plausible names and point sizes.
 *	Returns TRUE if found a more plausible candidate than previous best.
 */

bool
scanpdir(dir, fontptr, p_min_df, p_min_dp, p_min_dm)
char *dir;
struct font_entry *fontptr;
int *p_min_df, *p_min_dp, *p_min_dm;
{
	DIR *dirstream;
	struct direct *dirrecord;
	char qfamily[MAXPATHLEN];
	char qtype[MAXPATHLEN];
	int qpoint, qmag, df, dp, dm;
	bool status = FALSE;
	char family[MAXPATHLEN];
	int point;

	if(verbose & DEBUG_FONTS)
		fprintf(stderr, " scanpdir(%s .%dgf or .%dpxl)\n",
		  fontptr->n, fontptr->font_gf_mag, fontptr->font_pxl_mag);

	/*
	 * Split out family name, point size and magnification.
	 */
	if(sscanf(fontptr->n, "%[^0123456789.]%d", family, &point) != 2)
	{
		message("Font name \"%s\" appears garbled.", fontptr->n);
		return FALSE;
	}

	if(! (dirstream = opendir(dir)))
		return FALSE;

	while(dirrecord = readdir(dirstream))
	{
		if(sscanf(dirrecord->d_name, "%[^0123456789.]%d.%d%s",
		  qfamily, &qpoint, &qmag, qtype) != 4)
			continue;

		/*
		 * Is this a GF file.
		 */
		if(use_gf && strcmp(qtype, "gf") == 0)
		{
			df = strdiff(family, qfamily);
			dp = abs(point - qpoint);
			dm = abs(fontptr->font_gf_mag - qmag);
			if((df < *p_min_df) ||
			   (df == *p_min_df && dp < *p_min_dp) ||
			   (df == *p_min_df && dp == *p_min_dp &&
			     dm < *p_min_dm))
			{
				*p_min_df = df;
				*p_min_dp = dp;
				*p_min_dm = dm;

				sprintf(fontptr->name, "%s/%s",
				  dir, dirrecord->d_name);
				fontptr->type = TYPE_GF;

				if(verbose & DEBUG_FONTS)
					fprintf(stderr,
					  "  New best match (%d %d %d) is %s\n",
					  df, dp, dm, fontptr->name);

				status = TRUE;
			}
		}

		/*
		 * Is this a PXL file.
		 */
		if(use_pxl && strcmp(qtype, "pxl") == 0)
		{
			df = strdiff(family, qfamily);
			dp = abs(point - qpoint);
			dm = abs(fontptr->font_pxl_mag - qmag);
			if((df < *p_min_df) ||
			   (df == *p_min_df && dp < *p_min_dp) ||
			   (df == *p_min_df && dp == *p_min_dp &&
			     dm < *p_min_dm))
			{
				*p_min_df = df;
				*p_min_dp = dp;
				*p_min_dm = dm;

				sprintf(fontptr->name, "%s/%s",
				  dir, dirrecord->d_name);
				fontptr->type = TYPE_PXL;

				if(verbose & DEBUG_FONTS)
					fprintf(stderr,
					  "  New best match (%d %d %d) is %s\n",
					  df, dp, dm, fontptr->name);

				status = TRUE;
			}
		}
	}

	closedir(dirstream);

	return status;
}

/*
 * strdiff:
 *	Quantify differences in font names.
 */

int 
strdiff(s1, s2)
char *s1, *s2;
{
	register int diff = 0;

	while(*s1 && *s2)
		diff += abs(*s1++ - *s2++);
	while(*s1)
		diff += *s1++;
	while(*s2)
		diff += *s2++;

	return diff;
}