Back to index

tetex-bin  3.0
Defines | Functions | Variables
psearch.c File Reference
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include "ctype.h"
#include <stdio.h>
#include "stdlib.h"
#include <stdarg.h>
#include "string.h"
#include "basics.h"
#include "strexpr.h"
#include "filenames.h"
#include "texfiles.h"

Go to the source code of this file.

Defines

#define _POSIX_SOURCE   1
#define INT(x)   ((int)(x+0.5))

Functions

static void subtilde (char **fn, char **path)
char * path (char *deFault, char *env)
static char * rsearch (char *path, char *file)
int absname (char *name)
char * search_file (char *path, char *file, int terminate)
static void replace (char *cs, char *pattern, void *value)
void substitute (char *str, char *patterns,...)
void init_pksearch (int bdpi, char *mode, int margin, char *tolerance)
int evaluate (char *expr, int dpi)
int nearesthalf (int dpi)
char * search_pkfile (char *path, char *texfont, int dpi)
char * search_flifile (char *fliname, int(*font)(char *, int))
char * search_flipath (char *flipath, int(*font)(char *, int))

Variables

static int tilde = 0
static char * _mode = NULL
static int _margin = 0
static int _bdpi = -1
static char * _tolerance = NULL

Define Documentation

#define _POSIX_SOURCE   1

Definition at line 8 of file psearch.c.

#define INT (   x)    ((int)(x+0.5))

Definition at line 368 of file psearch.c.


Function Documentation

int absname ( char *  name)

Definition at line 211 of file psearch.c.

                        {

   if (*name == DIRSEP) return 1;
#ifdef MSDOS
   if (*(name+1) == ':' && *(name+2) == DIRSEP && isalpha(*name)) return 1;
#endif
   return 0;
}

Here is the caller graph for this function:

int evaluate ( char *  expr,
int  dpi 
)

Definition at line 356 of file psearch.c.

                                  {
   char expression[128];
   int result;

   if (expr == NULL || *expr == '\0') return 0;
   strcpy(expression, expr);
   substitute(expression, "%d", dpi);
   if (strexpr(&result, expression))
      fatal("%s: expression error\n", expression);
   return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void init_pksearch ( int  bdpi,
char *  mode,
int  margin,
char *  tolerance 
)

Definition at line 346 of file psearch.c.

                                                                      {
   _bdpi = bdpi;
   _mode = mode;
   _margin = margin;
   _tolerance = tolerance;
}
int nearesthalf ( int  dpi)

Definition at line 374 of file psearch.c.

                         {
   double near = _bdpi, half = 1.095445115; int tolerance;

   tolerance = evaluate(_tolerance, dpi);
   if (tolerance == 0 || dpi == _bdpi) return dpi;
   if (dpi > INT(near)+tolerance)
      while (dpi > INT(near)+tolerance) near*=half;
   else if (dpi < INT(near)-tolerance)
      while (dpi < INT(near)-tolerance) near/=half;
   if (dpi >= INT(near)-tolerance && dpi <= INT(near)+tolerance)
      return INT(near);
   return dpi;
}

Here is the call graph for this function:

char* path ( char *  deFault,
char *  env 
)

Definition at line 76 of file psearch.c.

                                     {
   char *e, *p, *q; int len, left = MAXPATHLEN;

   if (env == NULL) return deFault;

   p = (char *) malloc(MAXPATHLEN);
   if (p == NULL) fatal("Out of memory\n");

   q = p; e = env;
   while (*e) {
      if (*e == PATHSEP) {
         if (left == MAXPATHLEN) {
           len = strlen(deFault);
            if (len > left-1) fatal("'%s' path too long!\n", env);
           strcpy(q, deFault);
           q += len; left -= len;
           *q++ = *e++; left--;
        }
        else if (*(e+1) == PATHSEP || *(e+1) == '\0') {
           *q++ = *e++; left--;
            len = strlen(deFault);
           if (len > left) fatal("'%s' path too long!\n", env);     
            strcpy(q, deFault);
           q += len; left -= len;
        }
        else {
          *q++ = *e++; left--;
        }
      }
      else {
         *q++ = *e++; left--;
      }
      if (left == 0) fatal("'%s' path too long!\n", env);
   }
   *q = '\0';
   return p;
}

Here is the call graph for this function:

static void replace ( char *  cs,
char *  pattern,
void value 
) [static]

Definition at line 260 of file psearch.c.

                                                          {
   char temp[MAXPATHLEN], *p, *q; int len;

   while (q = strstr(cs, pattern)) {
      strcpy(temp, q+strlen(pattern));
      switch (*(pattern+1)) {
      case 'b':
      case 'd':
         sprintf(q, "%d", *((int *)value));
         len = strlen(q);
         break;
      case 'F':
         sprintf(q, "%-8s", (char *) value);
         len = strlen (q);
         break;
      case 'f':
         sprintf(q, "%s", (char *) value);
         len = strlen (q);
         break;
      default:
         sprintf(q, "%s", (char *) value);
         len = strlen (q);
         break;
      }
      strcpy(q+len, temp);
   }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* rsearch ( char *  path,
char *  file 
) [static]

Definition at line 119 of file psearch.c.

{
   struct stat status;
   DIR *D;
   struct dirent *de;
   int i;
   char *res = NULL, *ext, *file_ext,
        head[MAXPATHLEN], target[MAXPATHLEN], *tail;
   char fn[MAXPATHLEN];

   /* determine head and tail of path */
   i = 0;
   while (*(path+i) != '\0' && strncmp(path+i, RECURSIVE, 2) != 0) {
      head[i] = *(path+i); i++;
   }
   head[i] = '\0';
   if (*(path+i) == '\0') tail = NULL;
   else tail = path+i+2;

   /* Check if we have found <file> */
   if (tail == NULL || *tail == '\0') {
      sprintf(fn, "%s%c%s", head, DIRSEP, file);
      if (stat(fn, &status) == 0) {
        res = malloc(strlen(fn)+1);
        if (res == NULL) fatal("Out of memory\n");
        strcpy(res, fn);
        return res;
      }
      /* No recursion, so stop */
      if (tail == NULL) return NULL;
   }

   if ((D = opendir(head)) == NULL) return NULL;
   file_ext = extension(file);

   /* now read directories and probe files */
   while ((de = readdir(D)) != NULL) {
      /* Ignore `.' and `..' directories */
      if (strcmp(de->d_name, ".") == 0) continue;
      if (strcmp(de->d_name, "..") == 0) continue;

      /* Check if we have a directory */
      sprintf(fn, "%s%c%s", head, DIRSEP, de->d_name);
      (void) stat(fn, &status);
      if (!S_ISDIR(status.st_mode)) {
         /* if we are looking for a file with an extension and we find
          * files with the same or a different extension we may consider
          * this directory as a wrong place unless the user has defined
          * funny directory search paths
          */
         if (file_ext && (ext = extension(de->d_name))) {
            if (equal(ext, ".pk")) break;
            if (equal(ext, ".vf")) break;
            if (equal(ext, ".mf")) break;
            if (equal(ext, ".tfm")) break;
            if (equal(ext, ".afm")) break;
         }
         continue;
      }

      /* Directories with no real subdirectories can be skipped
       * unless the file we are looking for is there. Unfortunately
       * this shortcut only works for UNIX systems. On other systems
       * the above check on extensions may help.
       */
#if defined(UNIX)
      if (status.st_nlink == 2) {
        if (strchr(file, DIRSEP)) continue;
        if ((*tail == '\0') && (res = rsearch(fn, file))) break;
        continue;
      }
#endif

      /* path of the form "/aap/noot/mies//" */
      if (*tail == '\0') {
         sprintf(fn, "%s%c%s%s", head, DIRSEP, de->d_name, RECURSIVE);
        if (res = rsearch(fn, file)) break;
        continue;
      }
      
      /* path of the form "/aap/noot//mies" */

      /* search /aap/noot/<d_name>// <tail>/<file> */
      sprintf(fn, "%s%c%s%s", head, DIRSEP, de->d_name, RECURSIVE);
      sprintf(target, "%s%c%s", tail, DIRSEP, file);
      if (res = rsearch(fn, target)) break;
   }
   closedir(D);
   return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* search_file ( char *  path,
char *  file,
int  terminate 
)

Definition at line 225 of file psearch.c.

                                                         {
   char *fn, pe[MAXPATHLEN], *ppe, *ppath;
   struct stat status;

   if (path == NULL || *path == '\0' || absname(file)) {
      if (stat(file, &status) == 0) return file;
      if (terminate) fatal("File <%s> not found\n", file);
      return NULL;
   }
   ppath = path;
   while (*ppath) {
      /* copy next pathelement into pe */
      ppe = pe;
      while (*ppath != PATHSEP && *ppath != '\0') {
         if (tilde && *ppath == '~')
            subtilde(&ppe, &ppath);
         else
            *ppe++ = *ppath++;
      }
      *ppe = '\0';
      if (*ppath == PATHSEP) ppath++;
      if (fn = rsearch(pe, file)) return fn;
   }
   if (terminate) fatal("File <%s> not found in path \"%s\"\n", file, path);
   return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* search_flifile ( char *  fliname,
int(*)(char *, int font 
)

Definition at line 474 of file psearch.c.

                                                              {
   unsigned short len, numsizes, numfonts, version1, version2;
   char fontname[50];
   int i, size;

   FILE *FLI;

   FLI = fopen(fliname, RB);
   if (FLI == NULL) return NULL;

   for (i=0; i<4; i++) {
      fontname[i] = one(FLI);  /* read header */
   }
   version1 = one(FLI);
   version2 = one(FLI);
   if (strncmp(fontname,"FLIB",4)!=0 || version1 != 2 || version2 != 0)
      fatal("incorrect font library format");

   (void) two(FLI);        /* ignore directory length */
   numsizes = two(FLI);    /* number of sizes */
   numfonts = two(FLI);    /* number of fonts */
   len = two(FLI);         /* length of comment */
   for (i=0; i<len; i++)
      (void)one(FLI);      /* skip comment */

   for ( ;numsizes>0; numsizes--) { 
      /* for each font size in this library */
      (void)two(FLI);      /* length of size entry - ignore */
      numfonts = two(FLI); /* number of fonts */
                        /* DPI (fixed point 16.16) */
      size = (int)(four(FLI)/65536.0+0.5);
 
      for ( ;numfonts > 0; numfonts--) {
         /* read each entry */
         (void)four(FLI);           /* ignore length of font */
         (void)four(FLI);           /* offset to font */
         len = one(FLI);            /* length of name */
         for (i=0; i<len; i++)
            fontname[i] = one(FLI);
         fontname[len] = '\0';
        if (font(fontname, size) == 1) {
            fclose(FLI);
           return fliname;
        };
      }
   }
   fclose(FLI);
   return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* search_flipath ( char *  flipath,
int(*)(char *, int font 
)

Definition at line 529 of file psearch.c.

                                                              {
   char fn[MAXPATHLEN], *pfn, *pfli, *fliname;
   int len;

   if (flipath == NULL) fatal("Invalid fli path\n");

   /* treat first element of flipath as a directory */
   pfn = fn;
   while (*flipath != PATHSEP && *flipath != '\0') {
      *pfn++ = *flipath++;
   }
   *pfn = '\0'; len = strlen(fn);
   if (len >= 1 && fn[len-1] != DIRSEP) *pfn++ = DIRSEP;

   /* and next elements as fli files */
   while (*flipath != '\0') {
      /* copy next pathelement into fn */
      pfli = pfn; flipath++;
      while (*flipath != PATHSEP && *flipath != '\0') {
         *pfli++ = *flipath++;
      }
      *pfli = '\0'; len = strlen(pfn);
      if (len > 4 && strcmp(pfli-4, ".fli") != 0)
         strcat(pfli, ".fli");
      if ((fliname = search_flifile(fn, font)) != NULL)
        return fliname;
   }
   return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* search_pkfile ( char *  path,
char *  texfont,
int  dpi 
)

Definition at line 415 of file psearch.c.

                                                        {
   char *ppe, *pkpath, pe[MAXPATHLEN];
   int del;
   char *pkname;
   struct stat status;

   for (del=0; del <= _margin ; del=del>0?-del:-del+1) {
      pkpath = path;
      while (*pkpath) {
         /* copy next pathelement into pe */
         ppe = pe;
         while (*pkpath != PATHSEP && *pkpath != '\0') {
            if (tilde && *pkpath == '~')
               subtilde(&ppe, &pkpath);
            else
               *ppe++ = *pkpath++;
         }
         *ppe = '\0';
         if (strchr(pe, '%')) {
            if (strstr(pe, "%d") && strstr(pe, "%f")) {
               /* try filename after replacing placeholders */
               substitute(pe, "%b%m%f%d%p",
                _bdpi, _mode, texfont, dpi+del, "pk");
              if (stat(pe, &status) == 0) {
                  pkname = malloc(strlen(pe)+1);
                  if (pkname == NULL) fatal("Out of memory\n");
                  strcpy(pkname, pe);
                  return pkname;
               }
            }
            else /* %f and %d are required! */
               fatal("%s: incomplete path element!\n", pe);
         }
         else {
           sprintf(ppe, "%c%s.%dpk", DIRSEP, texfont, dpi+del);
            if (stat(pe, &status) == 0) {
               pkname = malloc(strlen(pe)+1);
               if (pkname == NULL) fatal("Out of memory\n");
               strcpy(pkname, pe);
               return pkname;
            }
         }
         if (*pkpath == PATHSEP) pkpath++;
      }
   }
   return NULL;
}

Here is the call graph for this function:

void substitute ( char *  str,
char *  patterns,
  ... 
)

Definition at line 298 of file psearch.c.

                                                {
   va_list ap;
   char *p;
   char *svalue; int ivalue;

   /* get arguments ... */
   va_start(ap, patterns);
   for (p = patterns; *p; p++) {
      if (*p != '%') {
        fatal("%s: invalid format\n");
      }
      switch (*++p) {
      case 'b':
         ivalue = va_arg(ap, int);
        replace(str, "%b", &ivalue);
        break;
      case 'd':
         ivalue = va_arg(ap, int);
        replace(str, "%d", &ivalue);
        break;
      case 'F':
         svalue = va_arg(ap, char *);
        replace(str, "%F", svalue);
        break;
      case 'f':
         svalue = va_arg(ap, char *);
        replace(str, "%f", svalue);
        break;
      case 'm':
         svalue = va_arg(ap, char *);
        replace(str, "%m", svalue);
        break;
      case 'p':
         svalue = va_arg(ap, char *);
        replace(str, "%p", svalue);
        break;
      default:
        fatal("%s: invalid letter (%c) in format\n", patterns, *p);
      }
   }
   va_end(ap);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void subtilde ( char **  fn,
char **  path 
) [static]

Definition at line 67 of file psearch.c.

{}

Here is the caller graph for this function:


Variable Documentation

int _bdpi = -1 [static]

Definition at line 343 of file psearch.c.

int _margin = 0 [static]

Definition at line 343 of file psearch.c.

char* _mode = NULL [static]

Definition at line 342 of file psearch.c.

char* _tolerance = NULL [static]

Definition at line 344 of file psearch.c.

int tilde = 0 [static]

Definition at line 66 of file psearch.c.