summaryrefslogtreecommitdiff
path: root/systems/knuth/local/texware/dvityext.c
blob: 61f20538a5a3ca716f8cf4b0b8eed4f033b2d9c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/* External procedures for texware				*/
/*   Written by Don Knuth, 2000.04.29, based on Trickey's vintage 1983 code */

#include "../texpaths.h"		/* defines default TEXFONTS path */
#include "../GPCtypes.h"		/* defines Pascal I/O structure */
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>

#define namelength 100          /* should agree with .ch files */

void Argv(int n, char* str)
{
  register char *s,*t;
  if (n<0 || n>=_p_argc) return;
  s=_p_argv[n];
  if (strlen(s) >= namelength-5) {
    str[0]='\0'; return; /* we don't want it too long */
  }
  for (t=str; *s; s++,t++) *t=*s;
  *t='\0';
}

bool Testreadaccess(char *fn)
{
  return access(fn,R_OK)? FALSE: TRUE;
}

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;
}

#define namelength 100   /* should agree with dvitype.ch */
char Curname[namelength],Realnameoffile[namelength];
#define curname Curname
#define realnameoffile Realnameoffile

/*
 *	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

bool
Testaccess(int amode,int 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,R_OK)==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; close(f);}
	    else ok = FALSE;
	    }
    } while (!ok && curpathplace != NULL);
    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) {
	if (realname >= &(realnameoffile[namelength-1])) {
	    fprintf(stderr,"! Full file name is too long\n");
	    break;
	    }
	*realname++ = *p++;
	}
    *realname = '\0';
}

int Flength(FDR filep)
{
  register FILE	*iop;	/* stdio-style FILE pointer */
  register long	pos;    /* current file position */
  register int	len;	/* the file length */

  iop = filep->FilJfn;
  pos = ftell(iop);
  fseek(iop,0L,SEEK_END);
  len = ftell(iop);
  fseek(iop,pos,0);
  return len;
}

void Bseek(FDR filep,int cnt)
{
  register FILE *iop; /* stdio-style FILE pointer */

  iop = filep->FilJfn;
  fseek(iop,(long)cnt,SEEK_SET);
}

void Flushstdout()
{
  fflush(stdout);
}

void Readbyte(FDR filep, unsigned char *x)
{ 
  /* reads a character WITHOUT using the Pascal runtime buffers etc */
  register int c;
  c=getc(filep->FilJfn);
  if (c==EOF) c=0;
  *x=c;
}