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