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