1 /************************************************************************/
2 /*									*/
3 /*  Implements a mapping between font names as implemented by the	*/
4 /*  GhostScript 'Fontmap' file.						*/
5 /*									*/
6 /************************************************************************/
7 
8 #   include	"appUtilConfig.h"
9 
10 #   include	<stdio.h>
11 #   include	<stddef.h>
12 #   include	<stdlib.h>
13 #   include	<string.h>
14 #   include	<ctype.h>
15 
16 #   include	"appSystem.h"
17 #   include	"utilFontmap.h"
18 
19 #   include	<appDebugon.h>
20 
21 typedef struct FontmapEntry
22     {
23     char *		feFrom;
24     char *		feTo;
25     int			feIsAlias;
26     } FontmapEntry;
27 
28 static FontmapEntry *	UTIL_FontmapEntries;
29 static int		UTIL_FontmapEntryCount;
30 
31 /************************************************************************/
32 /*									*/
33 /*  Get a name resulting from one of the mappings.			*/
34 /*									*/
35 /************************************************************************/
36 
utilFontmapGet(const char * from,const FontmapEntry * entries,int entryCount)37 static const char *	utilFontmapGet(	const char *		from,
38 					const FontmapEntry *	entries,
39 					int			entryCount )
40     {
41     int			turn;
42 
43     for ( turn= 0; turn < 20; turn++ )
44 	{
45 	const FontmapEntry *	fe;
46 	int			i;
47 
48 	fe= entries;
49 	for ( i= 0; i < entryCount; fe++, i++ )
50 	    {
51 	    if  ( ! strcmp( fe->feFrom, from ) )
52 		{ break;	}
53 	    }
54 
55 	if  ( i >= entryCount )
56 	    { return (const char *)0;	}
57 
58 	if  ( fe->feIsAlias )
59 	    { from= fe->feTo; continue;	}
60 
61 	return fe->feTo;
62 	}
63 
64     LSDEB(turn,from);
65     return (const char *)0;
66     }
67 
utilFontmapGetEntry(const char * from)68 const char * utilFontmapGetEntry(	const char *	from )
69     {
70     return utilFontmapGet( from,
71 			UTIL_FontmapEntries, UTIL_FontmapEntryCount );
72     }
73 
74 /************************************************************************/
75 /*									*/
76 /*  Read the GhostScript font map.					*/
77 /*									*/
78 /*  1)  Syntax error in the Cyrillic fonts section.			*/
79 /*	As usual, people do not follow their own file format.		*/
80 /*  2)  The standard GhostScript distribution comes with a reference	*/
81 /*	to Fontmap.greek in Fontmap. As this file does not exist and	*/
82 /*	GhostScript seems to enjoy this kind of a mess, only include	*/
83 /*	existing files.	(This is an aspect of Macho culture.. tidiness	*/
84 /*	seems to be for girls and weaklings.)				*/
85 /*									*/
86 /************************************************************************/
87 
utilFontmapNextItem(FILE * f)88 static int utilFontmapNextItem(	FILE *	f )
89     {
90     int		c;
91 
92     c= getc( f );
93     for (;;)
94 	{
95 	if  ( c == '%' )
96 	    {
97 	    c= getc( f );
98 	    while( c != EOF && c != '\n' )
99 		{ c= getc( f );	}
100 
101 	    if  ( c == '\n' )
102 		{ c= getc( f );	}
103 
104 	    continue;
105 	    }
106 
107 	if  ( isspace( c ) )
108 	    { c= getc( f ); continue;	}
109 
110 	break;
111 	}
112 
113     return c;
114     }
115 
utilFontmapReadMap(const char * filename)116 int utilFontmapReadMap(	const char *	filename )
117     {
118     int		rval= 0;
119     FILE *	f= (FILE *)0;
120     int		c;
121 
122     static int	recursive= 0;
123 
124     static const char runlibfile[]= ".runlibfile";
125 
126     MemoryBuffer	fileBuf;
127     MemoryBuffer	runfile;
128     MemoryBuffer	local;
129 
130     utilInitMemoryBuffer( &fileBuf );
131     utilInitMemoryBuffer( &runfile );
132     utilInitMemoryBuffer( &local );
133 
134     recursive++;
135 
136     if  ( recursive == 1 && UTIL_FontmapEntryCount > 0 )
137 	{ /* LDEB(UTIL_FontmapEntryCount); rval= -1; */ goto ready;	}
138 
139     if  ( recursive > 20 )
140 	{ LDEB(recursive); rval= -1; goto ready;	}
141 
142     if  ( utilMemoryBufferSetString( &fileBuf, filename ) )
143 	{ LDEB(1); rval= -1; goto ready;	}
144 
145     f= fopen( filename, "r" );
146     if  ( ! f )
147 	{ SXDEB(filename,f); rval= -1; goto ready;	}
148 
149     c= utilFontmapNextItem( f );
150     while( c != EOF )
151 	{
152 	FontmapEntry *	fe;
153 
154 	char		scratch[200+ 1];
155 	int		l;
156 
157 	switch( c )
158 	    {
159 	    case ';':
160 		/*  1  */
161 		c= utilFontmapNextItem( f );
162 		continue;
163 
164 	    case '(':
165 		for ( l= 0; l < 200; l++ )
166 		    {
167 		    c= getc( f );
168 		    if  ( c == EOF )
169 			{ LDEB(c); rval= -1; goto ready;	}
170 		    if  ( c == ')' )
171 			{ break;	}
172 
173 		    scratch[l]= c;
174 		    }
175 		if  ( l >= 200 )
176 		    { LDEB(l); rval= -1; goto ready;	}
177 		scratch[l]= '\0';
178 
179 		c= getc( f );
180 		if  ( c == EOF )
181 		    { LDEB(c); rval= -1; goto ready;	}
182 
183 		while( isspace( c ) )
184 		    {
185 		    c= getc( f );
186 		    if  ( c == EOF )
187 			{ LDEB(c); rval= -1; goto ready;	}
188 		    }
189 
190 		for ( l= 0; l < sizeof(runlibfile)- 1; l++ )
191 		    {
192 		    if  ( c != runlibfile[l] )
193 			{ SCDEB(runlibfile+l,c); rval= -1; goto ready; }
194 		    c= getc( f );
195 		    }
196 
197 		while( isspace( c ) && c != '\n' )
198 		    {
199 		    c= getc( f );
200 		    if  ( c == EOF )
201 			{ LDEB(c); rval= -1; goto ready;	}
202 		    }
203 
204 		if  ( c != '\n' )
205 		    { CDEB(c); rval= -1; goto ready; }
206 
207 		if  ( utilMemoryBufferSetString( &local, scratch ) )
208 		    { LDEB(l); rval= -1; goto ready;	}
209 
210 		if  ( appAbsoluteName( &runfile, &local, 1, &fileBuf ) < 0 )
211 		    { SSDEB(filename,scratch); rval= -1; goto ready;	}
212 
213 		/*  2  */
214 		if  ( ! appTestFileExists( &runfile )	&&
215 		      utilFontmapReadMap( utilMemoryBufferGetString( &runfile ) ) )
216 		    { LDEB(1); rval= -1; goto ready;	}
217 
218 		c= utilFontmapNextItem( f );
219 		continue;
220 
221 	    case '/':
222 		break;
223 
224 	    default:
225 		CDEB(c);
226 		rval= -1; goto ready;
227 	    }
228 
229 	fe= (FontmapEntry *)realloc( UTIL_FontmapEntries,
230 			( UTIL_FontmapEntryCount+ 1)* sizeof(FontmapEntry) );
231 	if  ( ! fe )
232 	    { LXDEB(UTIL_FontmapEntryCount,fe); rval= -1; goto ready; }
233 	UTIL_FontmapEntries= fe;
234 	fe += UTIL_FontmapEntryCount;
235 
236 	for ( l= 0; l < 200; l++ )
237 	    {
238 	    c= getc( f );
239 	    if  ( c == EOF )
240 		{ LDEB(c); rval= -1; goto ready;	}
241 	    if  ( isspace( c ) )
242 		{ break;	}
243 
244 	    scratch[l]= c;
245 	    }
246 	if  ( l >= 200 )
247 	    { LDEB(l); rval= -1; goto ready;	}
248 	scratch[l]= '\0';
249 
250 	fe->feFrom= strdup( scratch );
251 	if  ( ! fe->feFrom )
252 	    { XDEB(fe->feFrom); rval= -1; goto ready;	}
253 
254 	while( isspace( c ) )
255 	    {
256 	    c= getc( f );
257 	    if  ( c == EOF )
258 		{ LDEB(c); rval= -1; goto ready;	}
259 	    }
260 
261 	switch( c )
262 	    {
263 	    case '/':
264 		fe->feIsAlias= 1;
265 		break;
266 	    case '(':
267 		fe->feIsAlias= 0;
268 		break;
269 	    default:
270 		CDEB(c); rval= -1; goto ready;
271 	    }
272 
273 	for ( l= 0; l < 200; l++ )
274 	    {
275 	    c= getc( f );
276 	    if  ( c == EOF )
277 		{ LDEB(c); rval= -1; goto ready;	}
278 	    if  ( isspace( c ) )
279 		{ break;	}
280 
281 	    scratch[l]= c;
282 	    }
283 	if  ( l >= 200 )
284 	    { LDEB(l); rval= -1; goto ready;	}
285 	scratch[l]= '\0';
286 
287 	if  ( ! fe->feIsAlias )
288 	    {
289 	    if  ( l < 1 || scratch[l-1] != ')' )
290 		{ SDEB(scratch); rval= -1; goto ready;	}
291 
292 	    scratch[l-1]= '\0';
293 	    }
294 
295 	fe->feTo= strdup( scratch );
296 	if  ( ! fe->feTo )
297 	    { XDEB(fe->feTo); rval= -1; goto ready;	}
298 
299 	while( isspace( c ) )
300 	    {
301 	    c= getc( f );
302 	    if  ( c == EOF )
303 		{ LDEB(c); rval= -1; goto ready;	}
304 	    }
305 
306 	if  ( c != ';' )
307 	    { CDEB(c); rval= -1; goto ready;	}
308 
309 	UTIL_FontmapEntryCount++;
310 	c= utilFontmapNextItem( f );
311 	}
312 
313   ready:
314 
315     recursive--;
316 
317     if  ( f )
318 	{ fclose( f );	}
319 
320     utilCleanMemoryBuffer( &fileBuf );
321     utilCleanMemoryBuffer( &runfile );
322     utilCleanMemoryBuffer( &local );
323 
324     return rval;
325     }
326 
327