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