]> git.donarmstrong.com Git - lilypond.git/blob - lily/kpath.cc
* lily/kpath.cc (kpathsea_gulp_file_to_string):
[lilypond.git] / lily / kpath.cc
1 /*   
2   kpath.cc -- glue kpathsea to lily. Need some ugly kludges for gcc 2.96
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2000--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include <stdio.h>
10 #include <string.h>
11
12 /*
13
14 The problem, as far as I can tell, is that MacOS X has its getopt
15 prototype in <unistd.h>, while I think other operating systems have it
16 in other places. <unistd.h> is included by kpathsea.h, so you end up
17 renaming both conflicting prototypes to YAKLUDGE.
18
19 I found a somewhat more elegant patch for this: Just #include
20 <unistd.h> before defining YAKLUDGE.
21
22 */
23 #include <unistd.h>     
24 #include "config.h"
25
26 #define popen REALLYUGLYKLUDGE
27 #define pclose ANOTHERREALLYUGLYKLUDGE
28 #define getopt YAKLUDGE
29
30 #if HAVE_KPATHSEA_KPATHSEA_H
31 extern "C" {
32 #include <kpathsea/kpathsea.h>
33 #include <kpathsea/tex-file.h>
34 }
35 #endif
36
37 #include "file-path.hh"
38 #include "string.hh"
39 #include "main.hh"
40 #include "kpath.hh"
41 #include "source-file.hh"
42 #include "warn.hh"
43
44 String
45 kpathsea_find_afm (char const * name)
46 {
47 #if (KPATHSEA && HAVE_KPSE_FIND_FILE)
48   char * name_ptr =  kpse_find_file (name, kpse_afm_format, true);
49
50   if (!name_ptr)
51     {
52   /*
53     don't mutter about afms, since we try to find them first, and lots of
54     TFMs don't have AFMs. 
55    */
56       //      warning (_f ("kpathsea couldn't find AFM file `%s'", name));
57     }
58   else
59     return name_ptr;
60   
61 #endif
62   return "";
63 }
64
65 String
66 kpathsea_find_tfm (char const * name)
67 {
68   String p = global_path.find (String (name) + ".tfm");
69
70   if (p.length ())
71     return p;
72   
73 #if (KPATHSEA && HAVE_KPSE_FIND_FILE)
74   char * name_ptr =  kpse_find_file (name, kpse_tfm_format, true);
75   if (!name_ptr)
76     warning (_f ("kpathsea can not find TFM file: `%s'", name));
77   else
78     return name_ptr;
79   
80 #endif
81   return "";
82 }
83
84 #if KPATHSEA
85 /* FIXME: this should be part of kpathsea */
86
87 static kpse_file_format_type
88 kpathsea_find_format (String name)
89 {
90   for (int i = 0; i < kpse_last_format; i++)
91     {
92       if (!kpse_format_info[i].type)
93         kpse_init_format ((kpse_file_format_type) i);
94
95       char const **suffixes[] = { kpse_format_info[i].suffix,
96                                   kpse_format_info[i].alt_suffix };
97       for (int j = 0; j < 2; j++)
98         for (char const **p = suffixes[j]; p && *p; p++)
99           {
100             String suffix = *p;
101             if (name.right_string (suffix.length ()) == suffix)
102               return (kpse_file_format_type) i;
103           }
104     }
105   return kpse_last_format;
106 }
107 #endif
108
109 String
110 kpathsea_gulp_file_to_string (String name)
111 {
112   String filename = global_path.find (name);
113
114 #if (KPATHSEA && HAVE_KPSE_FIND_FILE)
115   if (filename.is_empty ())
116     {
117       char *p = kpse_find_file (name.to_str0 (), kpathsea_find_format (name),
118         true);
119       if (p)
120         filename = p;
121       else
122         warning (_f ("kpathsea can not find file: `%s'", name));
123     }
124 #endif
125
126   if (filename.is_empty ())
127     error (_f ("can't find file: `%s'", name));
128
129   if (verbose_global_b)
130     progress_indication ("[" + filename);
131
132   int filesize;
133   char *str = gulp_file (filename, &filesize);
134   String string (str);
135   delete[] str;
136   
137   if (verbose_global_b)
138     progress_indication ("]");
139
140   return string;
141 }
142
143 LY_DEFINE (ly_kpathsea_gulp_file, "ly:kpathsea-gulp-file",
144            1, 0, 0, (SCM name),
145            "Read the file @var{name}, and return its contents in a string.  "
146            "The file is looked up using the search path and kpathsea.")
147 {
148   SCM_ASSERT_TYPE (gh_string_p (name), name, SCM_ARG1, __FUNCTION__, "string");
149   return scm_makfrom0str
150     (kpathsea_gulp_file_to_string (ly_scm2string (name)).to_str0 ());
151 }
152
153 void
154 initialize_kpathsea (char *av0)
155 {
156 #if KPATHSEA && HAVE_KPATHSEA_KPATHSEA_H
157   /*
158     We take two pronged approach to tfms:
159
160     * the lilypond tfms (feta*.tfm) are found through our own routines.
161
162     * the TeX tfms are found through vanilla kpathsea.
163
164     (* other TFMs are not found, i.e. don't use them. )
165
166     PRO:
167  
168     - TFM and AFM checksums always match in Lily.
169
170     - less hassle, no kpathsea spaghetti
171
172     CON:
173
174     - feta PK files are often recreated, locally
175     Solution: cache PK files locally?
176
177     - need env. vars to make sure that TeX finds the TFMs
178
179     - Outdated PK (TFM?) font files are not automatically removed,
180     since VERSION is not part of the standard location.
181
182
183     ALTERNATIVE
184
185     we have tried to come up with schemes that leave this kind of work
186     to kpathsea with objective of fixing the CONs, but miserably
187     failed. TeX installations and kpathsea itself form a buggy,
188     inconsistent, and unorderly mess.
189     
190   */
191
192   /*
193    initialize kpathsea
194    */
195   kpse_set_program_name (av0, NULL);
196   kpse_maketex_option ("tfm", TRUE);
197 #endif
198 }