]> git.lyx.org Git - lyx.git/blob - src/support/os_unix.cpp
71168643011108f00d6922b322e7bc0eb132ead6
[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         }
74         return i;
75 }
76
77
78 bool path_prefix_is(string const & path, string const & pre)
79 {
80 #ifdef __APPLE__
81         return path_prefix_is(const_cast<string &>(path), pre, CASE_UNCHANGED);
82 #else
83         return prefixIs(path, pre);
84 #endif
85 }
86
87
88 bool path_prefix_is(string & path, string const & pre, path_case how)
89 {
90 #ifdef __APPLE__
91         docstring const p1 = from_utf8(path);
92         docstring const p2 = from_utf8(pre);
93         docstring::size_type const p1_len = p1.length();
94         docstring::size_type const p2_len = p2.length();
95         docstring::size_type common_len = common_path(p1, p2);
96
97         if (p2[p2_len - 1] == '/' && p1_len != p2_len)
98                 ++common_len;
99
100         if (common_len != p2_len)
101                 return false;
102
103         if (how == CASE_ADJUSTED && !prefixIs(path, pre)) {
104                 if (p1_len < common_len)
105                         path = to_utf8(p2.substr(0, p1_len));
106                 else
107                         path = to_utf8(p2 + p1.substr(common_len,
108                                                         p1_len - common_len));
109         }
110
111         return true;
112 #else
113         // silence compiler warnings
114         (void)how;
115
116         return prefixIs(path, pre);
117 #endif
118 }
119
120
121 string external_path(string const & p)
122 {
123         return p;
124 }
125
126
127 string internal_path(string const & p)
128 {
129         return p;
130 }
131
132
133 string safe_internal_path(string const & p, file_access)
134 {
135         return p;
136 }
137
138
139 string external_path_list(string const & p)
140 {
141         return p;
142 }
143
144
145 string internal_path_list(string const & p)
146 {
147         return p;
148 }
149
150
151 string latex_path(string const & p)
152 {
153         return p;
154 }
155
156
157 bool is_valid_strftime(string const & p)
158 {
159         string::size_type pos = p.find_first_of('%');
160         while (pos != string::npos) {
161                 if (pos + 1 == string::npos)
162                         break;
163                 if (!containsOnly(p.substr(pos + 1, 1),
164                         "aAbBcCdDeEFgGhHIjklmMnOpPrRsStTuUVwWxXyYzZ%+"))
165                         return false;
166                 if (pos + 2 == string::npos)
167                       break;
168                 pos = p.find_first_of('%', pos + 2);
169         }
170         return true;
171 }
172
173
174 char const * popen_read_mode()
175 {
176         return "r";
177 }
178
179
180 string const & nulldev()
181 {
182         static string const nulldev_ = "/dev/null";
183         return nulldev_;
184 }
185
186
187 bool is_terminal(io_channel channel)
188 {
189         return isatty(channel);
190 }
191
192
193 shell_type shell()
194 {
195         return UNIX;
196 }
197
198
199 char path_separator()
200 {
201         return ':';
202 }
203
204
205 void windows_style_tex_paths(bool)
206 {}
207
208 bool canAutoOpenFile(string const & ext, auto_open_mode const mode)
209 {
210 #ifdef __APPLE__
211 // Reference: http://developer.apple.com/documentation/Carbon/Reference/LaunchServicesReference/
212         CFStringRef cfs_ext = CFStringCreateWithBytes(kCFAllocatorDefault,
213                                         (UInt8 *) ext.c_str(), ext.length(),
214                                         kCFStringEncodingISOLatin1, false);
215         // this is what we would like to do but it seems that the
216         // viewer for PDF is often quicktime...
217         //LSRolesMask role = (mode == VIEW) ? kLSRolesViewer :  kLSRolesEditor;
218         (void)mode;
219         LSRolesMask role = kLSRolesAll;
220         FSRef outAppRef;
221         OSStatus status =
222                 LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator,
223                                         cfs_ext, role, &outAppRef, NULL);
224         CFRelease(cfs_ext);
225
226         return status != kLSApplicationNotFoundErr;
227 #else
228         // silence compiler warnings
229         (void)ext;
230         (void)mode;
231
232         // currently, no default viewer is tried for non-windows system
233         // support for KDE/Gnome/Macintosh may be added later
234         return false;
235 #endif
236 }
237
238
239 bool autoOpenFile(string const & filename, auto_open_mode const mode)
240 {
241 #ifdef __APPLE__
242 // Reference: http://developer.apple.com/documentation/Carbon/Reference/LaunchServicesReference/
243         FSRef fileref;
244         OSStatus status =
245                 FSPathMakeRef((UInt8 *) filename.c_str(), &fileref, NULL);
246         if (status != 0)
247                 return false;
248
249         // this is what we would like to do but it seems that the
250         // viewer for PDF is often quicktime...
251         //LSRolesMask role = (mode == VIEW) ? kLSRolesViewer :  kLSRolesEditor;
252         (void)mode;
253         LSRolesMask role = kLSRolesAll;
254         FSRef outAppRef;
255
256         status = LSGetApplicationForItem(&fileref, role, &outAppRef, NULL);
257         if (status == kLSApplicationNotFoundErr)
258                 return false;
259
260         LSLaunchFSRefSpec inLaunchSpec;
261         inLaunchSpec.appRef = &outAppRef;
262         inLaunchSpec.numDocs = 1;
263         inLaunchSpec.itemRefs = &fileref;
264         inLaunchSpec.passThruParams = NULL;
265         inLaunchSpec.launchFlags = kLSLaunchDefaults;
266         inLaunchSpec.asyncRefCon = NULL;
267         status = LSOpenFromRefSpec(&inLaunchSpec, NULL);
268
269         return status != kLSApplicationNotFoundErr;
270 #else
271         // silence compiler warnings
272         (void)filename;
273         (void)mode;
274
275         // currently, no default viewer is tried for non-windows system
276         // support for KDE/Gnome/Macintosh may be added later
277         return false;
278 #endif
279 }
280
281
282 string real_path(string const & path)
283 {
284         char rpath[PATH_MAX + 1];
285         char * result = realpath(path.c_str(), rpath);
286         return FileName::fromFilesystemEncoding(result ? rpath : path).absFilename();
287 }
288
289 } // namespace os
290 } // namespace support
291 } // namespace lyx