~ubuntu-branches/ubuntu/precise/vflib3/precise

« back to all changes in this revision

Viewing changes to src/fsearch.c

  • Committer: Bazaar Package Importer
  • Author(s): Masayuki Hatta
  • Date: 2002-04-15 12:10:24 UTC
  • Revision ID: james.westby@ubuntu.com-20020415121024-cann32wucyfbq22f
Tags: upstream-3.6.12
ImportĀ upstreamĀ versionĀ 3.6.12

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * fsearch.c - search a file 
 
3
 * by Hirotsugu Kakugawa
 
4
 *
 
5
 *  28 May 1997  Added recursive file searching feature.
 
6
 *  24 Dec 1998  Added searching in "VFlib.fdb" file that contain file list
 
7
 *  21 Sep 1999  Added a feature to generate PK & GF files on the fly.
 
8
 *
 
9
 */
 
10
/*
 
11
 * Copyright (C) 1996-1999   Hirotsugu Kakugawa. 
 
12
 * All rights reserved.
 
13
 *
 
14
 * This file is part of the VFlib Library.  This library is free
 
15
 * software; you can redistribute it and/or modify it under the terms of
 
16
 * the GNU Library General Public License as published by the Free
 
17
 * Software Foundation; either version 2 of the License, or (at your
 
18
 * option) any later version.  This library is distributed in the hope
 
19
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
 
20
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 
21
 * PURPOSE.  See the GNU Library General Public License for more details.
 
22
 * You should have received a copy of the GNU Library General Public
 
23
 * License along with this library; if not, write to the Free Software
 
24
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
25
 */
 
26
 
 
27
#include "config.h"
 
28
#include "with.h"
 
29
#include <stdio.h>
 
30
#include <stdlib.h>
 
31
#include <ctype.h>
 
32
#ifdef HAVE_UNISTD_H
 
33
#  include <unistd.h>
 
34
#endif
 
35
#include <sys/types.h>
 
36
#include <sys/param.h>
 
37
 
 
38
#ifdef HAVE_DIRENT_H
 
39
 
 
40
# include <dirent.h>
 
41
#  define NAMLENGTH(dirent) strlen((dirent)->d_name)
 
42
 
 
43
#else /* not DIRENT */
 
44
 
 
45
# define dirent direct
 
46
# define NAMLENGTH(dirent)  ((dirent)->d_namlen)
 
47
 
 
48
#ifdef HAVE_SYS_NDIR_H
 
49
# include <sys/ndir.h>
 
50
#endif
 
51
 
 
52
#ifdef HAVE_SYS_DIR_H
 
53
# include <sys/dir.h>
 
54
#endif
 
55
 
 
56
#ifdef HAVE_NDIR_H
 
57
# include <ndir.h>
 
58
#endif
 
59
 
 
60
#endif /* not DIRENT */
 
61
 
 
62
#ifdef HAVE_SYS_STAT_H
 
63
#  ifdef __linux__
 
64
#    define __USE_BSD
 
65
#  endif
 
66
# include <sys/stat.h>
 
67
#endif
 
68
 
 
69
#include "VFlib-3_6.h"
 
70
#include "VFsys.h"
 
71
#include "consts.h"
 
72
#include "fsearch.h"
 
73
#include "texfonts.h"
 
74
#include "sexp.h"
 
75
#include "path.h"
 
76
#include "str.h"
 
77
 
 
78
#ifdef WITH_KPATHSEA
 
79
# include  "kpathsea/kpathsea.h"
 
80
#endif
 
81
 
 
82
 
 
83
#ifdef HAVE_DIRENT_H
 
84
# ifdef HAVE_SYS_STAT_H
 
85
#  ifdef HAVE_OPENDIR
 
86
#   define  RECURSIVE_FILE_SEARCH
 
87
#  endif
 
88
# endif
 
89
#endif
 
90
 
 
91
 
 
92
 
 
93
 
 
94
/**
 
95
 ** kpathsea
 
96
 **/
 
97
Private int        kps_switch = DEFAULT_KPS_SWITCH;
 
98
Private char      *kps_mode   = DEFAULT_KPS_MODE;
 
99
Private int        kps_dpi    = DEFAULT_KPS_DPI;
 
100
#ifdef WITH_KPATHSEA
 
101
Private char      *kps_path   = DEFAULT_KPS_PROGRAM_PATH;
 
102
#endif
 
103
Private char      *kps_prog   = DEFAULT_KPS_PROGRAM_NAME;
 
104
 
 
105
 
 
106
Glocal void
 
107
vf_kpathsea_init(char *prog, char *mode, int dpi, int kps_sw)
 
108
{
 
109
#ifdef WITH_KPATHSEA
 
110
  static int  inited_prog = 0;
 
111
  int   f;
 
112
#endif
 
113
 
 
114
  kps_switch  = kps_sw; 
 
115
  kps_dpi     = dpi; 
 
116
  if (mode != NULL)
 
117
    kps_mode  = mode;
 
118
  if (prog != NULL)
 
119
    kps_prog  = prog;
 
120
 
 
121
#ifdef WITH_KPATHSEA
 
122
  if (inited_prog == 1)
 
123
    return;
 
124
 
 
125
  inited_prog = 1;
 
126
 
 
127
  if (vf_dbg_kpathsea == 1){
 
128
    if (kps_switch == TRUE)
 
129
      printf(">>Kpathsea: enabled\n");
 
130
    else
 
131
      printf(">>Kpathsea: disabled\n");
 
132
  }
 
133
 
 
134
  if (vf_dbg_kpathsea == 1)
 
135
    printf(">>Kpathsea: mode=%s, dpi=%d program=%s\n",
 
136
           kps_mode, kps_dpi, kps_prog);
 
137
 
 
138
  kpse_set_program_name(kps_path, kps_prog);
 
139
  kpse_init_prog(kps_prog, kps_dpi, kps_mode, NULL);
 
140
  for (f = 0; f < kpse_last_format; f++) {
 
141
    kpse_init_format(f);
 
142
  }
 
143
#else
 
144
  if (vf_dbg_kpathsea == 1)
 
145
    printf(">>Kpathsea: disabled by configure\n");
 
146
#endif
 
147
}
 
148
 
 
149
 
 
150
 
 
151
/**
 
152
 **  VF_AddUncompresser()
 
153
 **/
 
154
 
 
155
Private SEXP_ALIST  vf_uncompresser_alist = NULL; 
 
156
 
 
157
Public int
 
158
vf_add_uncompresser_alist(SEXP_ALIST alist)
 
159
{
 
160
  SEXP  t;
 
161
 
 
162
  if (alist == NULL)
 
163
    return 0;
 
164
 
 
165
  if (!vf_sexp_alistp(alist)){
 
166
    fprintf(stderr, "VFlib Error [fsearch.c:VF_AddUncompresser]: %s\n",
 
167
            "Not an alist.");
 
168
    return -1;
 
169
  }
 
170
 
 
171
  t = vf_uncompresser_alist;
 
172
  vf_sexp_nconc(alist, t);
 
173
  vf_uncompresser_alist = alist;
 
174
 
 
175
  return 0;
 
176
}
 
177
 
 
178
 
 
179
Glocal FILE*
 
180
vf_open_uncompress_stream(char *compressed_file, char *uncompress_prog)
 
181
{
 
182
#ifndef HAVE_POPEN
 
183
 
 
184
  return NULL;
 
185
 
 
186
#else
 
187
 
 
188
  FILE  *fp;
 
189
  char  *cmdline;
 
190
 
 
191
  cmdline = malloc(strlen(uncompress_prog) + strlen(compressed_file) + 16);
 
192
  if (cmdline == NULL)
 
193
    return NULL;
 
194
  sprintf(cmdline, "%s %s", uncompress_prog, compressed_file);
 
195
  fp = popen(cmdline, "r");
 
196
  vf_free(cmdline);
 
197
 
 
198
  return fp;
 
199
 
 
200
#endif /* HAVE_POPEN */
 
201
}
 
202
 
 
203
Glocal int
 
204
vf_close_uncompress_stream(FILE* fp)
 
205
{
 
206
#ifdef HAVE_POPEN
 
207
 
 
208
  if (fp != NULL){
 
209
    pclose(fp);
 
210
  }
 
211
 
 
212
#endif
 
213
 
 
214
  return 0;
 
215
}
 
216
 
 
217
 
 
218
 
 
219
/**
 
220
 ** Search a File 
 
221
 **/
 
222
 
 
223
Private char *search_in_fdb(char *name, char *dir,
 
224
                            SEXP_LIST compressed_ext_list, 
 
225
                            char **p_uncompr_prog, int *ret_val);
 
226
Private int   search_fdb_fp(FILE *fp, char *d, char *f,
 
227
                            char *ret_path, int ret_path_size);
 
228
Private char *search_file_kpathsea(char*,int,char*,int);
 
229
Private char *search_file(char*,char*,SEXP_LIST,char**);
 
230
Private char *search_file_recursive(char*, char*,SEXP_LIST,char**);
 
231
Private int   ext2uncprog(char *ext, SEXP_LIST compressed_ext_list, 
 
232
                          char **p_uncompr_prog);
 
233
 
 
234
 
 
235
 
 
236
Glocal char*
 
237
vf_search_file(char *name, int opt_arg1, char *opt_arg2,
 
238
               int use_kpathsea, int kpathsea_file_format,
 
239
               SEXP_LIST dir_list, 
 
240
               SEXP_LIST compressed_ext_list, char **p_uncompr_prog)
 
241
     /* NOTE: CALLER OF THIS FUNCTION *SHOULD* RELEASE RETURN VALUE.
 
242
              (STRING RETURNED BY P_UNCOMPR_PROG SHOULD NOT BE RELEASED.) */
 
243
{
 
244
  SEXP   d;
 
245
  char  *path, *dir;
 
246
  int    v;
 
247
 
 
248
  if (name == NULL)
 
249
    return NULL;
 
250
 
 
251
  if (vf_dbg_font_search == 1){
 
252
    printf(">> File search: %s\n", name);
 
253
  }
 
254
 
 
255
  if (p_uncompr_prog != NULL)
 
256
    *p_uncompr_prog = NULL;
 
257
 
 
258
  if (vf_path_absolute(name)){
 
259
    if (vf_path_file_read_ok(name)){
 
260
      if (vf_dbg_font_search == 1)
 
261
        printf(">>  File search: Found %s\n", name);
 
262
      return vf_strdup(name);
 
263
    }
 
264
    if (vf_dbg_font_search == 1)
 
265
      printf(">>  File search: Not found (no such absolute path)\n");
 
266
    return NULL;
 
267
  }
 
268
 
 
269
  if ((dir_list == NULL) || (!vf_sexp_listp(dir_list))){
 
270
    if (vf_dbg_font_search == 1)
 
271
      printf(">>  File search: Not found (empty dir list)\n");
 
272
    return NULL;
 
273
  }
 
274
 
 
275
  path = NULL;
 
276
  for (d = dir_list; vf_sexp_consp(d); d = vf_sexp_cdr(d)){
 
277
    dir = vf_sexp_get_cstring(vf_sexp_car(d));
 
278
    if (dir == NULL)
 
279
      continue;
 
280
    if ((vf_strcmp_ci(dir, "TEXMF") == 0) 
 
281
        || (vf_strcmp_ci(dir, "KPATHSEA") == 0)){
 
282
      /* Search by 'KPATHSEA' */
 
283
      if (use_kpathsea == FALSE){
 
284
        fprintf(stderr, 
 
285
                "VFlib Warning: Unsupported file format by kpathsea.\n");
 
286
        continue;
 
287
      }
 
288
      if (kps_switch == FALSE)
 
289
        continue;
 
290
      path = search_file_kpathsea(name, opt_arg1, opt_arg2, 
 
291
                                  kpathsea_file_format);
 
292
    } else {
 
293
      /* check font file hint db */
 
294
      path = search_in_fdb(name, dir, compressed_ext_list, p_uncompr_prog, &v);
 
295
      if (v == -2){
 
296
        if (vf_path_terminated_by_2delims(dir) == FALSE){
 
297
          /* Search under dir */
 
298
          path = search_file(name, dir, compressed_ext_list, p_uncompr_prog);
 
299
        } else {
 
300
          /* Recursive search under dir */
 
301
          path = search_file_recursive(name, dir, 
 
302
                                       compressed_ext_list, p_uncompr_prog);
 
303
        }
 
304
      }
 
305
    }
 
306
 
 
307
    if (path != NULL)
 
308
      break;
 
309
  }
 
310
 
 
311
  if (vf_dbg_font_search == 1){
 
312
    if (path != NULL){
 
313
      printf(">>  File search: Found %s\n", path);
 
314
    } else {
 
315
      printf(">>  File search: Not found\n");
 
316
    }
 
317
  }
 
318
 
 
319
  if (path == NULL)
 
320
    return NULL;
 
321
 
 
322
  return path;
 
323
}
 
324
 
 
325
 
 
326
Private char*
 
327
search_in_fdb(char *name, char *dir,
 
328
              SEXP_LIST compressed_ext_list, char **p_uncompr_prog,
 
329
              int *p_ret_val)
 
330
     /* NOTE: CALLER OF THIS FUNCTION *SHOULD* RELEASE RETURN VALUE. */
 
331
{
 
332
  char   fdb[MAXPATHLEN], name_ext[MAXPATHLEN],  *path;
 
333
  int    pathsize;
 
334
  FILE  *fp;
 
335
  SEXP   s;
 
336
  char  *ext; 
 
337
 
 
338
  if (dir == NULL){
 
339
    *p_ret_val = -2;
 
340
    return NULL;
 
341
  }
 
342
 
 
343
  if ((vf_path_cons_path(fdb, sizeof(fdb), dir, VF_FONT_FILE_HINT_DB) < 0)
 
344
      || (! vf_path_file_read_ok(fdb))
 
345
      || ((fp = fopen(fdb, FOPEN_RD_MODE_TEXT)) == NULL)){
 
346
    if (vf_dbg_font_search == 1)
 
347
      printf(">> No font hint db file: %s\n", fdb);
 
348
    *p_ret_val = -2;  /* hint db not found */
 
349
    return NULL;  
 
350
  }
 
351
  
 
352
  if (vf_dbg_font_search == 1)
 
353
    printf(">> Reading hint db file: %s\n", fdb);
 
354
 
 
355
  pathsize = MAXPATHLEN;
 
356
  ALLOCN_IF_ERR(path, char, pathsize){
 
357
    *p_ret_val = -2;  /* hint db not found */
 
358
    fclose(fp);
 
359
    return NULL;
 
360
  }
 
361
 
 
362
  /* look for font without compression */
 
363
  if (search_fdb_fp(fp, dir, name, path, pathsize) >= 0){  /* found */
 
364
    *p_ret_val = 0; /* found */
 
365
    goto end;
 
366
  }
 
367
 
 
368
  /* look for font with compression */
 
369
  *p_ret_val = -1; 
 
370
  for (s = compressed_ext_list; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
 
371
    ext = vf_sexp_get_cstring(vf_sexp_car(s));
 
372
    strncpy(name_ext, name, sizeof(name_ext));
 
373
    strncat(name_ext, ext,  sizeof(name_ext) - strlen(name));
 
374
    fseek(fp, 0, SEEK_SET);
 
375
    if ((search_fdb_fp(fp, dir, name_ext, path, pathsize) >= 0) 
 
376
        && (ext2uncprog(ext, compressed_ext_list, p_uncompr_prog) >= 0)){
 
377
      *p_ret_val = 0;  /* found */
 
378
      break;
 
379
    }
 
380
  }
 
381
  
 
382
end:
 
383
  fclose(fp);
 
384
  if (*p_ret_val != 0){
 
385
    vf_free(path);
 
386
    path = NULL;
 
387
  }
 
388
 
 
389
  if (vf_dbg_font_search == 1){
 
390
    if (path != NULL)
 
391
      printf(">> Found in db file: %s\n", path);
 
392
    else
 
393
      printf(">> Not found in db file\n");
 
394
  }
 
395
 
 
396
  return path;
 
397
}
 
398
 
 
399
Private int
 
400
search_fdb_fp(FILE *fp, char *d, char *f, char *ret_path, int ret_path_size)
 
401
{
 
402
  char   linebuff[MAXPATHLEN], *p;
 
403
  int    flen, dlen, i;
 
404
 
 
405
  if ((fp == NULL) || (d == NULL) || (f == NULL) || (ret_path == NULL))
 
406
    return -1;
 
407
 
 
408
  dlen = strlen(d);
 
409
  flen = strlen(f);
 
410
  while (fgets(linebuff, sizeof(linebuff), fp) != NULL){
 
411
    if ((strncmp(f, linebuff, flen) == 0) && isspace((int)linebuff[flen])){
 
412
      for (p = &linebuff[flen]; (*p != '\0') && isspace((int)*p); p++)
 
413
        ;
 
414
      if (*p == '\0')
 
415
        break;
 
416
      for (i = 0; p[i] != '\0'; i++){
 
417
        if (isspace((int)p[i])){
 
418
          p[i] = '\0';
 
419
          break;
 
420
        }
 
421
      }
 
422
      vf_path_cons_path(ret_path, ret_path_size, d, p);
 
423
      return 0;
 
424
    }
 
425
  } 
 
426
 
 
427
  return -1;
 
428
}
 
429
 
 
430
 
 
431
 
 
432
Glocal char*
 
433
vf_find_file_in_directory(char *name, char *dir)
 
434
     /* NOTE: CALLER OF THIS FUNCTION *SHOULD* RELEASE RETURN VALUE. */
 
435
{
 
436
  return search_file(name, dir, NULL, NULL);
 
437
}
 
438
 
 
439
 
 
440
Private char*
 
441
search_file_kpathsea(char *name, int dpi, char *name2, int file_format)
 
442
     /* NOTE: CALLER OF THIS FUNCTION *SHOULD* RELEASE RETURN VALUE. */
 
443
{
 
444
#ifndef WITH_KPATHSEA
 
445
 
 
446
  return NULL;
 
447
 
 
448
#else 
 
449
 
 
450
  char   *s;
 
451
  kpse_glyph_file_type  g_ret;
 
452
 
 
453
#if 0
 
454
  printf("search_file_kpathsea(%s, %s, %d, %d)\n", 
 
455
         name, name2, dpi, file_format);
 
456
#endif
 
457
 
 
458
  if (kps_switch == FALSE)
 
459
    return NULL;
 
460
 
 
461
  if (vf_dbg_kpathsea == 1)
 
462
    printf(">> Kpathsea: Search %s\n", name);
 
463
 
 
464
  s = NULL;
 
465
 
 
466
  switch (file_format){
 
467
  case FSEARCH_FORMAT_TYPE_GF:
 
468
    s = kpse_find_gf(name2, dpi, &g_ret);
 
469
    break;
 
470
  case FSEARCH_FORMAT_TYPE_PK:
 
471
    s = kpse_find_pk(name2, dpi, &g_ret);
 
472
    break;
 
473
  case FSEARCH_FORMAT_TYPE_VF:
 
474
    s = kpse_find_vf(name);
 
475
    if (s == NULL)
 
476
      s = kpse_find_ovf(name);
 
477
    break;
 
478
  case FSEARCH_FORMAT_TYPE_TFM:
 
479
    s = kpse_find_tfm(name);
 
480
    if (s == NULL)
 
481
      s = kpse_find_ofm(name);
 
482
    break;
 
483
  case FSEARCH_FORMAT_TYPE_OVF:
 
484
    s = kpse_find_ovf(name);
 
485
    break;
 
486
  case FSEARCH_FORMAT_TYPE_OFM:
 
487
    s = kpse_find_ofm(name);
 
488
    break;
 
489
  case FSEARCH_FORMAT_TYPE_TTF:
 
490
    s = kpse_find_file(name, kpse_truetype_format, 0);
 
491
    break;
 
492
  case FSEARCH_FORMAT_TYPE_TYPE1:
 
493
    s = kpse_find_file(name, kpse_type1_format, 0);
 
494
    break;
 
495
  case FSEARCH_FORMAT_TYPE_TYPE42:
 
496
    s = kpse_find_file(name, kpse_type42_format, 0);
 
497
    break;
 
498
  case FSEARCH_FORMAT_TYPE_AFM:
 
499
    s = kpse_find_file(name, kpse_afm_format, 0);
 
500
    break;
 
501
  case FSEARCH_FORMAT_TYPE_PSHEADER:
 
502
    s = kpse_find_file(name, kpse_tex_ps_header_format, 0);
 
503
    break;
 
504
  default:
 
505
    s = NULL;
 
506
    break;
 
507
  }
 
508
 
 
509
  if (vf_dbg_kpathsea == 1){
 
510
    if (s != NULL){
 
511
      printf(">> Kpathsea: Found %s\n", s);
 
512
    } else {
 
513
      printf(">> Kpathsea: Not found\n");
 
514
    }
 
515
  }
 
516
 
 
517
  if (s == NULL)
 
518
    return NULL;
 
519
 
 
520
#if 0
 
521
  return vf_strdup(s);
 
522
#else
 
523
  return s;
 
524
#endif
 
525
 
 
526
#endif
 
527
}
 
528
 
 
529
Private char*
 
530
search_file(char *name, char *dir, 
 
531
            SEXP_LIST compressed_ext_list, char **p_uncompr_prog)
 
532
     /* NOTE: CALLER OF THIS FUNCTION *SHOULD* RELEASE RETURN VALUE. */
 
533
{
 
534
  char   *path;
 
535
  char   *ext = NULL;  
 
536
  int    path_len, found;
 
537
  SEXP   s;
 
538
 
 
539
  if ((dir != NULL) && (vf_path_directory_read_ok(dir) == FALSE))
 
540
    return NULL;
 
541
 
 
542
  if (dir == NULL)
 
543
    dir = "";
 
544
 
 
545
  path_len = strlen(dir) + strlen(name) + 64;
 
546
       /* +64 for compressed extensions. Their lengths must be less 64. */
 
547
  ALLOCN_IF_ERR(path, char, path_len){
 
548
    vf_error = VF_ERR_NO_MEMORY;
 
549
    return NULL;
 
550
  }
 
551
 
 
552
  /* search non-compressed file */
 
553
  vf_path_cons_path(path, path_len, dir, name);
 
554
  if (vf_path_file_read_ok(path))
 
555
    return path;
 
556
 
 
557
  if (compressed_ext_list == NULL){
 
558
    vf_free(path);
 
559
    return NULL;
 
560
  }
 
561
 
 
562
  /* search compressed file */
 
563
  found = 0;
 
564
  for (s = compressed_ext_list; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
 
565
    ext = vf_sexp_get_cstring(vf_sexp_car(s));
 
566
    vf_path_cons_path2(path, path_len, dir, name, ext);
 
567
    if (vf_path_file_read_ok(path) == TRUE){
 
568
      found = 1;
 
569
      break;
 
570
    }
 
571
  }
 
572
  if (found == 0){
 
573
    vf_free(path);
 
574
    return NULL;
 
575
  }
 
576
 
 
577
  if (ext2uncprog(ext, compressed_ext_list, p_uncompr_prog) < 0){
 
578
    vf_free(path);
 
579
    path = NULL;
 
580
  }
 
581
 
 
582
  return path;
 
583
}
 
584
 
 
585
 
 
586
/* Obtain uncompression program name from extension */
 
587
Private int
 
588
ext2uncprog(char *ext, SEXP_LIST compressed_ext_list, char **p_uncompr_prog)
 
589
     /* NOTE: CALLER OF THIS FUNCTION *SHOULD NOT* RELEASE 
 
590
        RETURN VALUE IN P_UNCOMPR_PROG. */
 
591
{
 
592
  char  *uncext;
 
593
  SEXP   p, q;
 
594
 
 
595
  if (p_uncompr_prog == NULL)
 
596
    return -1;
 
597
 
 
598
  *p_uncompr_prog = NULL;
 
599
  for (q = vf_uncompresser_alist; vf_sexp_consp(q); q = vf_sexp_cdr(q)){
 
600
    p = vf_sexp_car(q);
 
601
    uncext = vf_sexp_get_cstring(vf_sexp_car(p));
 
602
    if (strcmp(uncext, ext) == 0){
 
603
      *p_uncompr_prog = vf_sexp_get_cstring(vf_sexp_cadr(p));
 
604
      break;
 
605
    }
 
606
  }
 
607
  if (*p_uncompr_prog == NULL){
 
608
    fprintf(stderr, "VFlib Warning: %s %s\n",
 
609
            "Undefined uncompression program for file extension", ext);
 
610
    return -1;
 
611
  }
 
612
  if (vf_dbg_font_search == 1)
 
613
    printf(">>   Uncompression program: %s\n", *p_uncompr_prog);
 
614
  return 0;
 
615
}
 
616
 
 
617
 
 
618
Glocal int
 
619
vf_tex_make_glyph(int type, char *font_name, int dpi, double mag)
 
620
{
 
621
 
 
622
#ifndef WITH_KPATHSEA
 
623
 
 
624
  return -1;
 
625
 
 
626
#else
 
627
 
 
628
  char  *name,  *filename;
 
629
  char  *ext;
 
630
  int    kp_fmt;
 
631
  kpse_glyph_file_type file_ret;
 
632
 
 
633
  name = NULL;
 
634
 
 
635
  switch (type){
 
636
  case FSEARCH_FORMAT_TYPE_PK:
 
637
    ext = "pk";
 
638
    kp_fmt = kpse_pk_format;
 
639
    break;
 
640
  default:
 
641
    return -1;
 
642
  }
 
643
 
 
644
  if ((name = vf_path_base_core(font_name)) == NULL)
 
645
    return -1;
 
646
 
 
647
  fprintf(stderr, "Generating %s.%d%s (dpi=%d, mag=%.3f)...\n",
 
648
          name, (unsigned)(dpi*mag+0.5), ext, dpi, mag);
 
649
  fflush(stderr);
 
650
 
 
651
  kpse_set_program_enabled(kp_fmt, MAKE_TEX_PK_BY_DEFAULT, kpse_src_compile);
 
652
 
 
653
  filename = kpse_find_glyph(name, (unsigned)(dpi*mag+0.5), kp_fmt, &file_ret);
 
654
  if (filename == NULL){
 
655
    fprintf(stderr, "\nFailed.\n");
 
656
    vf_free(name);
 
657
    return -1;
 
658
  }
 
659
 
 
660
  fprintf(stderr, "Done.\n");
 
661
 
 
662
  vf_free(name);
 
663
  return 0;
 
664
 
 
665
#endif /*WITH_KPATHSEA*/
 
666
}
 
667
 
 
668
 
 
669
 
 
670
 
 
671
#ifndef RECURSIVE_FILE_SEARCH
 
672
 
 
673
Private char*
 
674
search_file_recursive(char *name, char *dir,
 
675
                      SEXP_LIST compressed_ext_list, char **p_uncompr_prog)
 
676
{
 
677
  char  *d, *path;
 
678
  int   len;
 
679
 
 
680
  if (dir == NULL)
 
681
    return NULL;
 
682
 
 
683
  len = strlen(dir) + 1;
 
684
  ALLOCN_IF_ERR(d, char, len){
 
685
    vf_error = VF_ERR_NO_MEMORY;
 
686
    return NULL;
 
687
  }
 
688
  strcpy(d, dir);
 
689
 
 
690
  vf_path_del_terminating_2delims(d);
 
691
  if (vf_path_directory_read_ok(d) == FALSE){
 
692
    vf_free(d);
 
693
    return NULL;
 
694
  }
 
695
  path = search_file(name, d, compressed_ext_list, p_uncompr_prog);
 
696
 
 
697
  vf_free(d);
 
698
  return path;
 
699
}
 
700
 
 
701
#else /*RECURSIVE_FILE_SEARCH*/
 
702
 
 
703
struct s_dtr_list {
 
704
  char              *name;
 
705
  struct stat       st;
 
706
  struct s_dtr_list *prev;
 
707
  struct s_dtr_list *next;
 
708
};
 
709
struct s_dtr_elem {
 
710
  int       path_index;
 
711
  dev_t     dev;
 
712
  ino_t     ino;
 
713
  struct s_dtr_elem   *next;
 
714
  struct s_dtr_elem   *prev;
 
715
  struct s_dtr_list   subdirs;
 
716
};
 
717
struct s_dtr {
 
718
  char      path[MAXPATHLEN];
 
719
  struct s_dtr_elem  *direc_head;
 
720
  struct s_dtr_elem  *direc_tail;
 
721
};
 
722
 
 
723
typedef struct s_dtr_list  *DTR_LIST;
 
724
typedef struct s_dtr_elem  *DTR_ELEM;
 
725
typedef struct s_dtr       *DTR;
 
726
 
 
727
Private DTR      dtr_alloc(char*);
 
728
Private void     dtr_free(DTR);
 
729
Private char*    dtr_get_path(DTR);
 
730
Private int      dtr_add_name(DTR, char*, int);
 
731
Private void     dtr_del_name(DTR);
 
732
Private int      dtr_add_subdir(DTR, struct dirent*, struct stat*);
 
733
Private DTR_LIST dtr_subdir_list(DTR);
 
734
Private DTR_LIST dtr_next_subdir(DTR, DTR_LIST);
 
735
Private int      dtr_go_subdir(DTR, DTR_LIST);
 
736
Private int      dtr_go_updir(DTR);
 
737
 
 
738
Private char *traverse_directory(DTR, char*, SEXP_LIST, char**);
 
739
 
 
740
 
 
741
Private char*
 
742
search_file_recursive(char *name, char *dir,
 
743
                      SEXP_LIST compressed_ext_list, char **p_uncompr_prog)
 
744
{
 
745
  char   *d, *path;
 
746
  int    len;
 
747
  DTR    dtr;
 
748
 
 
749
  if (dir == NULL)
 
750
    return NULL;
 
751
 
 
752
  len = strlen(dir) + 1;
 
753
  ALLOCN_IF_ERR(d, char, len){
 
754
    vf_error = VF_ERR_NO_MEMORY;
 
755
    return NULL;
 
756
  }
 
757
  strcpy(d, dir);
 
758
  vf_path_del_terminating_2delims(d);
 
759
 
 
760
  if (vf_path_directory_read_ok(d) == FALSE){
 
761
    vf_free(d);
 
762
    return NULL;
 
763
  }
 
764
 
 
765
  if (vf_dbg_font_search == 1)
 
766
    printf(">>  Search Recursively in: %s\n", d);
 
767
 
 
768
  if ((dtr = dtr_alloc(d)) == NULL){
 
769
    vf_free(d);
 
770
    return NULL;
 
771
  }
 
772
 
 
773
  path = traverse_directory(dtr, name, compressed_ext_list, p_uncompr_prog);
 
774
 
 
775
  dtr_free(dtr);
 
776
  vf_free(d);
 
777
 
 
778
  return path;
 
779
}
 
780
 
 
781
Private char*
 
782
traverse_directory(DTR dtr, char *name, 
 
783
                   SEXP_LIST compressed_ext_list, char **p_uncompr_prog)
 
784
{
 
785
  char           *path;
 
786
  int            v;
 
787
  DIR            *dir;
 
788
  DTR_LIST       sd;
 
789
  struct dirent  *ent;
 
790
  struct stat    st; 
 
791
  
 
792
  if (vf_dbg_font_search == 1)
 
793
    printf(">>    Searching in: %s\n", dtr_get_path(dtr));
 
794
 
 
795
  /* search a file in a directory */
 
796
  path = search_file(name, dtr_get_path(dtr), 
 
797
                     compressed_ext_list, p_uncompr_prog);
 
798
  if (path != NULL)
 
799
    return path;
 
800
 
 
801
  /* obtain a set of subdirectories in a directory */
 
802
  if ((dir = opendir(dtr_get_path(dtr))) == NULL)
 
803
    return NULL;
 
804
  while ((ent = readdir(dir)) != NULL){
 
805
    if ((NAMLENGTH(ent) == 1) && (strcmp(ent->d_name, ".") == 0))
 
806
      continue;
 
807
    if ((NAMLENGTH(ent) == 2) && (strcmp(ent->d_name, "..") == 0))
 
808
      continue;
 
809
 
 
810
    dtr_add_name(dtr, ent->d_name, NAMLENGTH(ent));
 
811
    v = stat(dtr_get_path(dtr), &st);
 
812
    dtr_del_name(dtr);
 
813
    if (v < 0)
 
814
      continue;
 
815
    if ((st.st_mode & S_IFMT) == S_IFDIR){
 
816
      dtr_add_subdir(dtr, ent, &st);
 
817
    }
 
818
  }
 
819
  closedir(dir);
 
820
 
 
821
  /* search a file under subdirectories */
 
822
  path = NULL;
 
823
  for (sd = dtr_subdir_list(dtr); sd != NULL; sd = dtr_next_subdir(dtr, sd)){
 
824
    if (dtr_go_subdir(dtr, sd) >= 0){
 
825
      path = traverse_directory(dtr, name,
 
826
                                compressed_ext_list, p_uncompr_prog);
 
827
      if (path != NULL)
 
828
        break;
 
829
      dtr_go_updir(dtr);
 
830
    }
 
831
  }
 
832
 
 
833
  return path;
 
834
}
 
835
 
 
836
 
 
837
Private DTR_ELEM
 
838
dtr_elem_alloc()
 
839
{
 
840
  DTR_ELEM  dtr_elem;
 
841
 
 
842
  if ((dtr_elem = (DTR_ELEM)malloc(sizeof(struct s_dtr_elem))) == NULL)
 
843
    return NULL;
 
844
 
 
845
  dtr_elem->path_index = 0;
 
846
  dtr_elem->dev     = 0;
 
847
  dtr_elem->ino     = 0;
 
848
  dtr_elem->next    = NULL;
 
849
  dtr_elem->prev    = NULL;
 
850
  dtr_elem->subdirs.name = NULL;
 
851
  dtr_elem->subdirs.prev = &dtr_elem->subdirs;
 
852
  dtr_elem->subdirs.next = &dtr_elem->subdirs;
 
853
  return dtr_elem;
 
854
}
 
855
 
 
856
Private void
 
857
dtr_elem_free(DTR_ELEM dtr_elem)
 
858
{
 
859
  DTR_LIST  dl, dl_next;
 
860
 
 
861
  dl = dtr_elem->subdirs.next;
 
862
  while (dl != &dtr_elem->subdirs){
 
863
    dl_next = dl->next;
 
864
    vf_free(dl->name);
 
865
    vf_free(dl);
 
866
    dl = dl_next;
 
867
  }
 
868
  vf_free(dtr_elem);
 
869
}
 
870
 
 
871
 
 
872
Private DTR
 
873
dtr_alloc(char *topdir)
 
874
{
 
875
  DTR         dtr;
 
876
  DTR_ELEM    dtr_elem;
 
877
  struct stat st; 
 
878
 
 
879
  if ((dtr = (DTR)malloc(sizeof(struct s_dtr))) == NULL)
 
880
    return NULL;
 
881
  dtr->direc_head = NULL;
 
882
  dtr->direc_tail = NULL;
 
883
  strcpy(dtr->path, topdir);
 
884
  vf_path_del_terminating_2delims(dtr->path);
 
885
  if (stat(dtr->path, &st) < 0)
 
886
    goto Error;
 
887
 
 
888
  if ((dtr_elem = dtr_elem_alloc()) == NULL)
 
889
    goto Error;
 
890
  dtr->direc_head = dtr_elem;
 
891
  dtr->direc_tail = dtr_elem;
 
892
  dtr_elem->path_index = strlen(dtr->path);
 
893
  dtr_elem->dev = st.st_dev;
 
894
  dtr_elem->ino = st.st_ino;
 
895
  return dtr;
 
896
 
 
897
Error: 
 
898
  dtr_free(dtr);
 
899
  return NULL;
 
900
}
 
901
 
 
902
Private void
 
903
dtr_free(DTR dtr)
 
904
{
 
905
  DTR_ELEM  dtr_elem, dtr_elem_next;
 
906
 
 
907
  if (dtr == NULL)
 
908
    return;
 
909
  dtr_elem = dtr->direc_head;
 
910
  while (dtr_elem != NULL){
 
911
    dtr_elem_next = dtr_elem->next;
 
912
    dtr_elem_free(dtr_elem);
 
913
    dtr_elem = dtr_elem_next;
 
914
  }
 
915
  vf_free(dtr);
 
916
}
 
917
 
 
918
Private char*
 
919
dtr_get_path(DTR dtr)
 
920
{
 
921
  return dtr->path;
 
922
}
 
923
 
 
924
Private int
 
925
dtr_add_subdir(DTR dtr, struct dirent *ent, struct stat* st)
 
926
{
 
927
  DTR_LIST  dl_new, dl_0, dl_1;
 
928
 
 
929
  if ((dl_new = (DTR_LIST)malloc(sizeof(struct s_dtr_list))) == NULL)
 
930
    return -1;
 
931
  if ((dl_new->name = (char*)malloc(NAMLENGTH(ent)+1)) == NULL){
 
932
    vf_free(dl_new);
 
933
    return -1;
 
934
  }
 
935
 
 
936
  memcpy(dl_new->name, ent->d_name, NAMLENGTH(ent));
 
937
  dl_new->name[NAMLENGTH(ent)] = '\0';
 
938
  memcpy(&dl_new->st, st, sizeof(struct stat));
 
939
 
 
940
  dl_0 = &dtr->direc_tail->subdirs;
 
941
  dl_1 = dl_0->next;
 
942
  dl_new->next = dl_1;
 
943
  dl_new->prev = dl_0;
 
944
  dl_0->next   = dl_new;
 
945
  dl_1->prev   = dl_new;
 
946
 
 
947
  return 0;
 
948
}
 
949
 
 
950
Private int
 
951
dtr_go_subdir(DTR dtr, DTR_LIST sd)
 
952
{
 
953
  DTR_ELEM     dtr_elem, elem;
 
954
  
 
955
  if (dtr_add_name(dtr, sd->name, strlen(sd->name)) < 0)
 
956
    return -1;
 
957
 
 
958
  for (elem = dtr->direc_head; elem != NULL; elem = elem->next){
 
959
    if ((elem->dev == sd->st.st_dev) && (elem->ino == sd->st.st_ino)){
 
960
      /* LOOP! */
 
961
      dtr_del_name(dtr);
 
962
      return -1;
 
963
    }
 
964
  }
 
965
 
 
966
  if ((dtr_elem = dtr_elem_alloc()) == NULL){
 
967
    dtr_del_name(dtr);
 
968
    return -1;
 
969
  }
 
970
 
 
971
  dtr_elem->path_index   = strlen(dtr->path);
 
972
  dtr_elem->dev          = sd->st.st_dev;
 
973
  dtr_elem->ino          = sd->st.st_ino;
 
974
  dtr_elem->prev         = dtr->direc_tail;
 
975
  dtr->direc_tail->next  = dtr_elem; 
 
976
  dtr->direc_tail        = dtr_elem;
 
977
 
 
978
  return 0;
 
979
}
 
980
 
 
981
Private int
 
982
dtr_go_updir(DTR dtr)
 
983
{
 
984
  DTR_ELEM   tail_elem;
 
985
 
 
986
  tail_elem = dtr->direc_tail;
 
987
  if (tail_elem == NULL){
 
988
    fprintf(stderr, "FATAL: CANNOT HAPPEN --- in dtr_go_updir().\n");
 
989
    exit(1);
 
990
  }
 
991
  tail_elem->prev->next = NULL;
 
992
  dtr->direc_tail = tail_elem->prev;
 
993
  dtr_elem_free(tail_elem);
 
994
 
 
995
  dtr_del_name(dtr);
 
996
 
 
997
  return 0;
 
998
}
 
999
 
 
1000
 
 
1001
Private DTR_LIST
 
1002
dtr_subdir_list(DTR dtr)
 
1003
{
 
1004
  DTR_LIST  sd;
 
1005
#if 0
 
1006
  DTR_LIST  ss;
 
1007
 
 
1008
  ss = dtr->direc_tail->subdirs.prev;
 
1009
  printf("  ");
 
1010
  while (ss != &dtr->direc_tail->subdirs){
 
1011
    printf("%s, ", ss->name);
 
1012
    ss = ss->prev;
 
1013
  }
 
1014
  printf("\n");
 
1015
#endif
 
1016
 
 
1017
  if ((sd = dtr->direc_tail->subdirs.prev) == &dtr->direc_tail->subdirs)
 
1018
    return NULL;
 
1019
 
 
1020
  return sd;
 
1021
}
 
1022
 
 
1023
Private DTR_LIST
 
1024
dtr_next_subdir(DTR dtr, DTR_LIST sd)
 
1025
{
 
1026
  DTR_LIST  next;
 
1027
 
 
1028
  if ((next = sd->prev) == &dtr->direc_tail->subdirs)
 
1029
    return NULL;
 
1030
  return next;
 
1031
}
 
1032
 
 
1033
 
 
1034
Private int 
 
1035
dtr_add_name(DTR dtr, char *name, int len)
 
1036
{
 
1037
  char  *p;
 
1038
  int   index;
 
1039
 
 
1040
  index = dtr->direc_tail->path_index;
 
1041
 
 
1042
  for (p = vf_directory_delimiter; *p != '\0'; p++){
 
1043
    dtr->path[index++] = *p;
 
1044
  }
 
1045
  while (len > 0){
 
1046
    dtr->path[index++] = *(name++);
 
1047
    --len;
 
1048
  }
 
1049
  dtr->path[index] = '\0';
 
1050
 
 
1051
  return 0;
 
1052
}
 
1053
 
 
1054
Private void
 
1055
dtr_del_name(DTR dtr)
 
1056
{
 
1057
  dtr->path[dtr->direc_tail->path_index] = '\0';
 
1058
}
 
1059
 
 
1060
#endif /* RECURSIVE_FILE_SEARCH */
 
1061
 
 
1062
 
 
1063
 
 
1064
 
 
1065
#if 0
 
1066
 
 
1067
Private int
 
1068
recursive_searcher(char *path, struct dirent *ent, struct stat *st)
 
1069
{
 
1070
  SEXP_ALIST   iter, q, s;
 
1071
  char         *ext, *uncext, *uncprog;
 
1072
  int          ext_len;
 
1073
 
 
1074
  if (rec_target_file_len > NAMLENGTH(ent))
 
1075
    return -1;
 
1076
  if (strncmp(ent->d_name, rec_target_file, rec_target_file_len) != 0)
 
1077
    return -1;
 
1078
 
 
1079
  if ((rec_target_file_len == NAMLENGTH(ent))
 
1080
      && (strncmp(rec_target_file, ent->d_name, NAMLENGTH(ent)) == 0)){
 
1081
    recursive_searcher_found(path);
 
1082
    return 1;
 
1083
  }
 
1084
 
 
1085
  if (rec_compressed_ext != NULL){
 
1086
    for (iter = rec_compressed_ext;
 
1087
         vf_sexp_consp(iter); 
 
1088
         iter = vf_sexp_cdr(iter)){
 
1089
      ext = vf_sexp_get_cstring(vf_sexp_car(iter));
 
1090
      if ((ext == NULL) || (strcmp(ext, "") == 0))
 
1091
        continue;
 
1092
      ext_len = strlen(ext);
 
1093
      if ((ext_len == (NAMLENGTH(ent) - rec_target_file_len))
 
1094
           && (strncmp(&ent->d_name[rec_target_file_len], ext, ext_len) == 0)){
 
1095
        uncprog = NULL;
 
1096
        for (s = vf_uncompresser_alist; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
 
1097
          q = vf_sexp_car(s);
 
1098
          uncext = vf_sexp_get_cstring(vf_sexp_car(q));
 
1099
          if (strcmp(uncext, ext) == 0){
 
1100
            uncprog = vf_sexp_get_cstring(vf_sexp_cadr(q));
 
1101
            break;
 
1102
          }
 
1103
        }
 
1104
        if (rec_p_uncompression_program != NULL)
 
1105
          *rec_p_uncompression_program = uncprog;
 
1106
        if (uncprog == NULL){
 
1107
          fprintf(stderr, "VFlib Warning: %s %s\n",
 
1108
                  "Undefined compression program for file extension", ext);
 
1109
          return -1;
 
1110
        }
 
1111
        if (vf_dbg_font_search == 1)
 
1112
          printf(">>       Uncompression program: %s\n", uncprog);
 
1113
        recursive_searcher_found(path);
 
1114
        return 1;
 
1115
      }
 
1116
    }
 
1117
  }
 
1118
 
 
1119
  return -1;
 
1120
}
 
1121
 
 
1122
Private void
 
1123
recursive_searcher_found(char *path)
 
1124
{
 
1125
  int  len;
 
1126
 
 
1127
  if ((len = strlen(file_path) + 32) > file_path_length){
 
1128
    vf_free(file_path);
 
1129
    file_path_length = len;
 
1130
    ALLOCN_IF_ERR(file_path, char, file_path_length){
 
1131
      file_path_length = 0;
 
1132
      vf_error = VF_ERR_NO_MEMORY;
 
1133
      return;
 
1134
    }
 
1135
  }
 
1136
  strcpy(file_path, path);
 
1137
  rec_found_file = file_path;
 
1138
}
 
1139
 
 
1140
#endif 
 
1141
 
 
1142
/*EOF*/