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