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 e

⟦de558d406⟧ TextFile

    Length: 6741 (0x1a55)
    Types: TextFile
    Names: »extra.c«

Derivation

└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦c319c2751⟧ »unix3.0/TeX3.0.tar.Z« 
        └─⟦036c765ac⟧ 
            └─⟦this⟧ »TeX3.0/fontutil/extra.c« 

TextFile

/* External procedures for these programs.

   02/04/90 Karl Berry
*/

#include "extra.h" /* Includes <stdio.h> and "site.h".  */

#ifdef SYSV
#define index strchr
#define rindex strrchr
#endif

extern char *getenv ();
extern char *index (), *rindex ();


static char **gargv;   /* The command line is stored here, since Pascal has 
			  usurped `argv' for a procedure.  */
integer argc;  /* Referenced from the Pascal, so not `static'.  */

/* These deal with Pascal vs. C strings.  */
static void make_c_string ();
static void make_pascal_string ();
static void terminate_with_null ();
static void terminate_with_space ();


/* The entry point.  We just have to set up the command line.  Pascal's
   main block is transformed into the procedure `main_body'.  */

void
main (ac, av)
  int ac;
  char **av;
{
  argc = ac;
  gargv = av;
  main_body ();
  exit (0);
}


/* Read the Nth argument from the command line.  BUF is a ``Pascal''
   string, i.e., it starts at index 1 and ends with a space.  */

void
argv (n, buf)
  int n;
  char buf[];
{
  (void) strcpy(buf+1, gargv[n]);
  (void) strcat(buf+1, " ");
}


\f


/* Round R to the nearest whole number.  */
integer
zround (r)
  double r;
{
  return r >= 0.0 ? (r + 0.5) : (r - 0.5);
}


\f


/* File operations.  */

/* Open a file; don't return if error.  NAME is a Pascal string.  */

FILE *
openf (name, mode)
  char *name;
  char *mode;
{
  FILE *result;
  char *cp;

  make_c_string (&name);
  
  result = fopen (name, mode);
  if (result)
    {}  return result;
    
  perror (name);
  exit (1);
  /*NOTREACHED*/
}


/* Return true if we're at the end of FILE, else false.  */

boolean
testeof (file)
  FILE *file;
{
  register int c;

  /* Maybe we're already at the end?  */
  if (feof (file))
    return true;

  if ((c = getc (file)) == EOF)
    return true;
  
  /* Whoops, we weren't at the end.  Back up.  */
  (void) ungetc (c, file);
  
  return false;
}


/* Return true on end-of-line in FILE or at the end of FILE, else false.  */

boolean
eoln (file)
  FILE *file;
{
  register int c;

  if (feof(file))
    return true;
  
  c = getc (file);
  
  if (c != EOF)
    (void) ungetc(c, file);
    
  return c == '\n' || c == EOF;
}


/* Print real number R in format N:M on stdout. */

void
printreal (r, n, m)
  double r;
  int n, m;
{
  char fmt[50];  /* Surely enough, since N and M won't be more than 25
                    digits each!  */

  (void) sprintf (fmt, "%%%d.%df", n, m);
  (void) printf (fmt, r);
}


/* Print S, a ``Pascal string'', on stdout.  It starts at index 1 and is
   terminated by a space.  */
void
printpascalstring (s)
  char *s;
{
  s++;
  while (*s != ' ') putchar (*s++);
}


/* Change the suffix of BASE (a Pascal string) to be SUFFIX (another
   Pascal string).  We have to change them to C strings to do the work,
   then convert them back to Pascal strings.  */

void
makesuffix (base, suffix)
  char *base;
  char *suffix;
{
  char *last_dot, *last_slash;
  make_c_string (&base);
  
  last_dot = rindex (base, '.');
  last_slash = rindex (base, '/');
  
  if (last_dot == NULL || last_dot < last_slash) /* Add the suffix?  */
    {
      make_c_string (&suffix);
      strcat (base, suffix);
      make_pascal_string (&suffix);
    }
    
  make_pascal_string (&base);
}
   
   
/* Deal with C and Pascal strings.  */

/* Change the Pascal string P_STRING into a C string; i.e., make it
   start after the leading character Pascal puts in, and terminate it
   with a null.  */

static void
make_c_string (p_string)
  char **p_string;
{
  (*p_string)++;
  terminate_with_null (*p_string);
}


/* Change the C string C_STRING into a Pascal string; i.e., make it
   start one character before it does now (so C_STRING had better have
   been a Pascal string originally), and terminate with a space.  */

static void
make_pascal_string (c_string)
  char **c_string;
{
  terminate_with_space (*c_string);
  (*c_string)--;
}


/* Replace the first space we come to with a null.  */

static void
terminate_with_null (s)
  char *s;
{
  while (*s++ != ' ')
    ;
  
  *(s-1) = 0;
}


/* Replace the first null we come to with a space.  */

static void
terminate_with_space (s)
  char *s;
{
  while (*s++ != 0)
    ;
  
  *(s-1) = ' ';
}


\f


/* Path searching.  I don't know why they don't start at zero.  */

#define NUMBER_OF_PATHS 6

static char *path[NUMBER_OF_PATHS];
static char *env_var_names[NUMBER_OF_PATHS]
  = { "TEXINPUTS", "TEXFONTS", "TEXFORMATS", "TEXPOOL", "GFFONTS", "PKFONTS" };

#define READ_ACCESS 4   /* Used in access(2) call.  */
#define PATH_DELIMITER ':'  /* For the sake of DOS, which wants `;'.  */

static void next_component ();


/* This sets up the paths, by either copying from an environment variable
   or using the default path, which is defined as a preprocessor symbol
   (of the same name as the environment variable) in site.h.  */

#define DO_PATH(p, default) \
  path[p] = getenv (env_var_names[p]); \
  if (path[p] == NULL) path[p] = default

extern void
setpaths ()
{
  /* DO_PATH (TEXINPUTPATH, TEXINPUTS); */
  DO_PATH (TFMFILEPATH, TEXFONTS);
  /* DO_PATH (TEXFORMATPATH, TEXFORMATS); */
  /* DO_PATH (TEXPOOLPATH, TEXPOOL); */
  /* If the environment variables GFFONTS/PKFONTS aren't set, we want to
     use TEXFONTS.  */
  DO_PATH (GFFILEPATH, path[TFMFILEPATH]);
  DO_PATH (PKFILEPATH, path[TFMFILEPATH]);
}


/* Look for NAME, a Pascal string, in a colon-separated list of
   directories.  The path to use is given (indirectly) by PATH_INDEX.
   If the search is successful, leave the full pathname in NAME (which
   therefore must have enough room for such a pathname), padded with
   blanks.  Otherwise, or if NAME is an absolute path, just leave it
   alone.  */

boolean
testreadaccess (name, path_index)
  char *name;
  int path_index;
{
  int ok;
  char potential[FILENAMESIZE];
  char *the_path = path[path_index];
  
  if (*(name+1) == '/') return true;  /* Absolute path.  */
  make_c_string (&name);
  
  do
    {
      next_component (potential, &the_path);

  if (*potential == 0) break;
  
      strcat (potential, "/");
      strcat (potential, name);
      ok = (access (potential, READ_ACCESS) == 0);
    }
  while (! ok);
  
  if (ok) strcpy (name, potential);

  make_pascal_string (&name);
  
  return ok;
}


/* Return, in NAME, the next component of PATH, i.e., the characters up
   to the next PATH_DELIMITER.  */
   
static void
next_component (name, path)
  char name[];
  char **path;
{
  unsigned count = 0;
  
  while (**path != 0 && **path != PATH_DELIMITER)
    {
      name[count++] = **path;
      (*path)++; /* Move further along, even between calls.  */
    }
  
  name[count] = 0;
  if (**path == PATH_DELIMITER)
    (*path)++; /* Move past the delimiter.  */
}