]> git.lyx.org Git - lyx.git/blob - src/support/os_unix.cpp
b7a5b10daa2a5332214dddf924ab4bdef1eb5d71
[lyx.git] / src / support / os_unix.cpp
1 /**
2  * \file os_unix.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Ruurd A. Reitsma
7  *
8  * Full author contact details are available in file CREDITS.
9  *
10  * Various OS specific functions
11  */
12
13 #include <config.h>
14
15 #include "support/os.h"
16 #include "support/docstring.h"
17 #include "support/FileName.h"
18 #include "support/lstrings.h"
19
20 #include <limits.h>
21 #include <stdlib.h>
22
23 #ifdef __APPLE__
24 #include <Carbon/Carbon.h>
25 #endif
26
27 using namespace std;
28
29 namespace lyx {
30 namespace support {
31 namespace os {
32
33 void init(int, char *[])
34 {}
35
36
37 string current_root()
38 {
39         return "/";
40 }
41
42
43 bool isFilesystemCaseSensitive()
44 {
45 #ifdef __APPLE__
46         return false;
47 #else
48         return true;
49 #endif
50 }
51
52
53 docstring::size_type common_path(docstring const & p1, docstring const & p2)
54 {
55         docstring::size_type i = 0;
56         docstring::size_type const p1_len = p1.length();
57         docstring::size_type const p2_len = p2.length();
58 #ifdef __APPLE__
59         while (i < p1_len && i < p2_len && uppercase(p1[i]) == uppercase(p2[i]))
60                 ++i;
61 #else
62         while (i < p1_len && i < p2_len && p1[i] == p2[i])
63                 ++i;
64 #endif
65         if ((i < p1_len && i < p2_len)
66             || (i < p1_len && p1[i] != '/' && i == p2_len)
67             || (i < p2_len && p2[i] != '/' && i == p1_len))
68         {
69                 if (i)
70                         --i;     // here was the last match
71                 while (i && p1[i] != '/')
72                         --i;
73         } else
74                 --i;
75
76         return i;
77 }
78
79
80 bool path_prefix_is(string const & path, string const & pre)
81 {
82 #ifdef __APPLE__
83         return path_prefix_is(const_cast<string &>(path), pre, CASE_UNCHANGED);
84 #else
85         return prefixIs(path, pre);
86 #endif
87 }
88
89
90 bool path_prefix_is(string & path, string const & pre, path_case how)
91 {
92 #ifdef __APPLE__
93         docstring const p1 = from_utf8(path);
94         docstring const p2 = from_utf8(pre);
95         docstring::size_type const p1_len = p1.length();
96         docstring::size_type const p2_len = p2.length();
97         docstring::size_type const common_len = common_path(p1, p2) + 1;
98
99         if (common_len == 1) {
100                 if (p2_len != 1 || p1_len == 0 || p1[0] != p2[0]
101                     || (p1_len != 1 && p1[1] != '/'))
102                         return false;
103         } else if (common_len != p2_len)
104                 return false;
105
106         if (how == CASE_ADJUSTED && !prefixIs(path, pre))
107                 path = to_utf8(p2 + p1.substr(common_len, p1_len - common_len));
108
109         return true;
110 #else
111         // silence compiler warnings
112         (void)how;
113
114         return prefixIs(path, pre);
115 #endif
116 }
117
118
119 string external_path(string const & p)
120 {
121         return p;
122 }
123
124
125 string internal_path(string const & p)
126 {
127         return p;
128 }
129
130
131 string external_path_list(string const & p)
132 {
133         return p;
134 }
135
136
137 string internal_path_list(string const & p)
138 {
139         return p;
140 }
141
142
143 string latex_path(string const & p)
144 {
145         return p;
146 }
147
148
149 bool is_valid_strftime(string const & p)
150 {
151         string::size_type pos = p.find_first_of('%');
152         while (pos != string::npos) {
153                 if (pos + 1 == string::npos)
154                         break;
155                 if (!containsOnly(p.substr(pos + 1, 1),
156                         "aAbBcCdDeEFgGhHIjklmMnOpPrRsStTuUVwWxXyYzZ%+"))
157                         return false;
158                 if (pos + 2 == string::npos)
159                       break;
160                 pos = p.find_first_of('%', pos + 2);
161         }
162         return true;
163 }
164
165
166 char const * popen_read_mode()
167 {
168         return "r";
169 }
170
171
172 string const & nulldev()
173 {
174         static string const nulldev_ = "/dev/null";
175         return nulldev_;
176 }
177
178
179 bool is_terminal(io_channel channel)
180 {
181         return isatty(channel);
182 }
183
184
185 shell_type shell()
186 {
187         return UNIX;
188 }
189
190
191 char path_separator()
192 {
193         return ':';
194 }
195
196
197 void windows_style_tex_paths(bool)
198 {}
199
200 bool canAutoOpenFile(string const & ext, auto_open_mode const mode)
201 {
202 #ifdef __APPLE__
203 // Reference: http://developer.apple.com/documentation/Carbon/Reference/LaunchServicesReference/
204         CFStringRef cfs_ext = CFStringCreateWithBytes(kCFAllocatorDefault,
205                                         (UInt8 *) ext.c_str(), ext.length(),
206                                         kCFStringEncodingISOLatin1, false);
207         // this is what we would like to do but it seems that the
208         // viewer for PDF is often quicktime...
209         //LSRolesMask role = (mode == VIEW) ? kLSRolesViewer :  kLSRolesEditor;
210         (void)mode;
211         LSRolesMask role = kLSRolesAll;
212         FSRef outAppRef;
213         OSStatus status =
214                 LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator,
215                                         cfs_ext, role, &outAppRef, NULL);
216         CFRelease(cfs_ext);
217
218         return status != kLSApplicationNotFoundErr;
219 #else
220         // silence compiler warnings
221         (void)ext;
222         (void)mode;
223
224         // currently, no default viewer is tried for non-windows system
225         // support for KDE/Gnome/Macintosh may be added later
226         return false;
227 #endif
228 }
229
230
231 bool autoOpenFile(string const & filename, auto_open_mode const mode)
232 {
233 #ifdef __APPLE__
234 // Reference: http://developer.apple.com/documentation/Carbon/Reference/LaunchServicesReference/
235         FSRef fileref;
236         OSStatus status =
237                 FSPathMakeRef((UInt8 *) filename.c_str(), &fileref, NULL);
238         if (status != 0)
239                 return false;
240
241         // this is what we would like to do but it seems that the
242         // viewer for PDF is often quicktime...
243         //LSRolesMask role = (mode == VIEW) ? kLSRolesViewer :  kLSRolesEditor;
244         (void)mode;
245         LSRolesMask role = kLSRolesAll;
246         FSRef outAppRef;
247
248         status = LSGetApplicationForItem(&fileref, role, &outAppRef, NULL);
249         if (status == kLSApplicationNotFoundErr)
250                 return false;
251
252         LSLaunchFSRefSpec inLaunchSpec;
253         inLaunchSpec.appRef = &outAppRef;
254         inLaunchSpec.numDocs = 1;
255         inLaunchSpec.itemRefs = &fileref;
256         inLaunchSpec.passThruParams = NULL;
257         inLaunchSpec.launchFlags = kLSLaunchDefaults;
258         inLaunchSpec.asyncRefCon = NULL;
259         status = LSOpenFromRefSpec(&inLaunchSpec, NULL);
260
261         return status != kLSApplicationNotFoundErr;
262 #else
263         // silence compiler warnings
264         (void)filename;
265         (void)mode;
266
267         // currently, no default viewer is tried for non-windows system
268         // support for KDE/Gnome/Macintosh may be added later
269         return false;
270 #endif
271 }
272
273
274 string real_path(string const & path)
275 {
276         char rpath[PATH_MAX + 1];
277         char * result = realpath(path.c_str(), rpath);
278         return FileName::fromFilesystemEncoding(result ? rpath : path).absFilename();
279 }
280
281 } // namespace os
282 } // namespace support
283 } // namespace lyx