3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Ruurd A. Reitsma
8 * Full author contact details are available in file CREDITS.
10 * Various OS specific functions
17 #include "support/os.h"
18 #include "support/docstring.h"
19 #include "support/environment.h"
20 #include "support/FileName.h"
21 #include "support/filetools.h"
22 #include "support/lstrings.h"
23 #include "support/lassert.h"
30 #include <CoreServices/CoreServices.h>
31 #include <CoreFoundation/CoreFoundation.h>
32 #include <CoreFoundation/CFArray.h>
48 void init(int argc, char ** argv[])
53 // Set environment's default locale
54 setlocale(LC_ALL, "");
55 setlocale(LC_NUMERIC, "C");
59 string utf8_argv(int i)
61 LASSERT(i < argc_, return "");
62 return to_utf8(from_local8bit(argv_[i]));
66 void remove_internal_args(int, int)
76 bool isFilesystemCaseSensitive()
86 docstring::size_type common_path(docstring const & p1, docstring const & p2)
88 docstring::size_type i = 0;
89 docstring::size_type const p1_len = p1.length();
90 docstring::size_type const p2_len = p2.length();
92 while (i < p1_len && i < p2_len && uppercase(p1[i]) == uppercase(p2[i]))
95 while (i < p1_len && i < p2_len && p1[i] == p2[i])
98 if ((i < p1_len && i < p2_len)
99 || (i < p1_len && p1[i] != '/' && i == p2_len)
100 || (i < p2_len && p2[i] != '/' && i == p1_len))
103 --i; // here was the last match
104 while (i && p1[i] != '/')
111 bool path_prefix_is(string const & path, string const & pre)
114 return path_prefix_is(const_cast<string &>(path), pre, CASE_UNCHANGED);
116 return prefixIs(path, pre);
121 bool path_prefix_is(string & path, string const & pre, path_case how)
124 docstring const p1 = from_utf8(path);
125 docstring const p2 = from_utf8(pre);
126 docstring::size_type const p1_len = p1.length();
127 docstring::size_type const p2_len = p2.length();
128 docstring::size_type common_len = common_path(p1, p2);
130 if (p2[p2_len - 1] == '/' && p1_len != p2_len)
133 if (common_len != p2_len)
136 if (how == CASE_ADJUSTED && !prefixIs(path, pre)) {
137 if (p1_len < common_len)
138 path = to_utf8(p2.substr(0, p1_len));
140 path = to_utf8(p2 + p1.substr(common_len,
141 p1_len - common_len));
146 // silence compiler warnings
149 return prefixIs(path, pre);
154 string external_path(string const & p)
160 string internal_path(string const & p)
166 string safe_internal_path(string const & p, file_access)
172 string external_path_list(string const & p)
178 string internal_path_list(string const & p)
184 string latex_path(string const & p)
190 string latex_path_list(string const & p)
196 bool is_valid_strftime(string const & p)
198 string::size_type pos = p.find_first_of('%');
199 while (pos != string::npos) {
200 if (pos + 1 == string::npos)
202 if (!containsOnly(p.substr(pos + 1, 1),
203 "aAbBcCdDeEFgGhHIjklmMnOpPrRsStTuUVwWxXyYzZ%+"))
205 if (pos + 2 == string::npos)
207 pos = p.find_first_of('%', pos + 2);
213 char const * popen_read_mode()
219 string const & nulldev()
221 static string const nulldev_ = "/dev/null";
232 char path_separator(path_type)
238 void windows_style_tex_paths(bool)
241 bool canAutoOpenFile(string const & ext, auto_open_mode const mode)
244 // Reference: http://developer.apple.com/documentation/Carbon/Reference/LaunchServicesReference/
245 CFStringRef cfs_ext = CFStringCreateWithBytes(kCFAllocatorDefault,
246 (UInt8 *) ext.c_str(), ext.length(),
247 kCFStringEncodingISOLatin1, false);
248 // this is what we would like to do but it seems that the
249 // viewer for PDF is often quicktime...
250 //LSRolesMask role = (mode == VIEW) ? kLSRolesViewer : kLSRolesEditor;
252 LSRolesMask role = kLSRolesAll;
255 LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator,
256 cfs_ext, role, &outAppRef, NULL);
259 return status != kLSApplicationNotFoundErr;
261 // silence compiler warnings
265 // currently, no default viewer is tried for non-windows system
266 // support for KDE/Gnome/Macintosh may be added later
272 bool autoOpenFile(string const & filename, auto_open_mode const mode,
276 // Reference: http://developer.apple.com/documentation/Carbon/Reference/LaunchServicesReference/
277 // this is what we would like to do but it seems that the
278 // viewer for PDF is often quicktime...
279 //LSRolesMask role = (mode == VIEW) ? kLSRolesViewer : kLSRolesEditor;
281 LSRolesMask role = kLSRolesAll;
283 CFURLRef docURL = CFURLCreateFromFileSystemRepresentation(
284 NULL, (UInt8 *) filename.c_str(), filename.size(), false);
286 OSStatus status = LSGetApplicationForURL(docURL, role, NULL, &appURL);
287 if (status == kLSApplicationNotFoundErr)
290 CFURLRef docURLs[] = { docURL };
291 CFArrayRef launchItems = CFArrayCreate(
293 (const void**)docURLs, sizeof(docURLs) / sizeof(CFURLRef),
295 LSLaunchURLSpec launchUrlSpec = {
296 appURL, launchItems, NULL, kLSLaunchDefaults, NULL
299 string const texinputs = os::latex_path_list(
300 replaceCurdirPath(path, lyxrc.texinputs_prefix));
301 string const otherinputs = os::latex_path_list(path);
302 string const oldtexinputs = getEnv("TEXINPUTS");
303 string const newtexinputs = ".:" + texinputs + ":" + oldtexinputs;
304 string const oldbibinputs = getEnv("BIBINPUTS");
305 string const newbibinputs = ".:" + otherinputs + ":" + oldbibinputs;
306 string const oldbstinputs = getEnv("BSTINPUTS");
307 string const newbstinputs = ".:" + otherinputs + ":" + oldbstinputs;
308 string const oldtexfonts = getEnv("TEXFONTS");
309 string const newtexfonts = ".:" + otherinputs + ":" + oldtexfonts;
310 if (!path.empty() && !lyxrc.texinputs_prefix.empty()) {
311 setEnv("TEXINPUTS", newtexinputs);
312 setEnv("BIBINPUTS", newbibinputs);
313 setEnv("BSTINPUTS", newbstinputs);
314 setEnv("TEXFONTS", newtexfonts);
316 status = LSOpenFromURLSpec (&launchUrlSpec, NULL);
317 CFRelease(launchItems);
318 if (!path.empty() && !lyxrc.texinputs_prefix.empty()) {
319 setEnv("TEXINPUTS", oldtexinputs);
320 setEnv("BIBINPUTS", oldbibinputs);
321 setEnv("BSTINPUTS", oldbstinputs);
322 setEnv("TEXFONTS", oldtexfonts);
326 // silence compiler warnings
331 // currently, no default viewer is tried for non-windows system
332 // support for KDE/Gnome/Macintosh may be added later
338 string real_path(string const & path)
340 #ifdef HAVE_DEF_PATH_MAX
341 char rpath[PATH_MAX + 1];
342 char * result = realpath(path.c_str(), rpath);
343 return FileName::fromFilesystemEncoding(result ? rpath : path).absFileName();
345 char * result = realpath(path.c_str(), NULL);
346 string ret = FileName::fromFilesystemEncoding(result ? result : path).absFileName();
353 } // namespace support