]> git.lyx.org Git - lyx.git/blob - src/support/os_cygwin.C
Fix mess up of internal/external paths (from Enrico Forestieri)
[lyx.git] / src / support / os_cygwin.C
1 /**
2  * \file os_cygwin.C
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  * \author Claus Hentschel
8  * \author Angus Leeming
9  *
10  * Full author contact details are available in file CREDITS.
11  *
12  * Various OS specific functions
13  */
14
15 #include <config.h>
16
17 #include "support/os.h"
18 #include "support/lstrings.h"
19
20 #include "debug.h"
21
22 #include <windows.h>
23 #include <io.h>
24
25 #include <sys/cygwin.h>
26
27 using std::endl;
28 using std::string;
29
30 using lyx::support::contains;
31
32
33 namespace lyx {
34 namespace support {
35 namespace os {
36
37 void os::init(int, char *[])
38 {}
39
40
41 string current_root()
42 {
43         return string("/");
44 }
45
46
47 string::size_type common_path(string const & p1, string const & p2)
48 {
49         string::size_type i = 0;
50         string::size_type       p1_len = p1.length();
51         string::size_type       p2_len = p2.length();
52         while (i < p1_len && i < p2_len && uppercase(p1[i]) == uppercase(p2[i]))
53                 ++i;
54         if ((i < p1_len && i < p2_len)
55             || (i < p1_len && p1[i] != '/' && i == p2_len)
56             || (i < p2_len && p2[i] != '/' && i == p1_len))
57         {
58                 if (i)
59                         --i;     // here was the last match
60                 while (i && p1[i] != '/')
61                         --i;
62         }
63         return i;
64 }
65
66
67 namespace {
68
69 bool cygwin_path_fix_ = false;
70
71 // In both is_posix_path() and is_windows_path() it is assumed that
72 // a valid posix or pseudo-windows path is passed. They simply tell
73 // whether the path looks posix/pseudo-windows or not.
74
75 bool is_posix_path(string const & p)
76 {
77         return  p.empty() ||
78                 (!contains(p, '\\') && (p.length() <= 1 || p[1] != ':'));
79 }
80
81 // This is a test for a win32 style path with forward slashes (pseudo-windows).
82
83 bool is_windows_path(string const & p)
84 {
85         return p.empty() ||
86                 (!contains(p, '\\') && (p.length() <= 1 || p[1] == ':'));
87 }
88
89
90 enum PathStyle {
91     posix,
92     windows
93 };
94
95
96 string convert_path(string const & p, PathStyle const & target)
97 {
98         char path_buf[PATH_MAX];
99
100         if ((target == posix && is_posix_path(p)) ||
101             (target == windows && is_windows_path(p)))
102                 return p;
103
104         path_buf[0] = '\0';
105
106         if (target == posix)
107                 cygwin_conv_to_posix_path(p.c_str(), path_buf);
108         else
109                 cygwin_conv_to_win32_path(p.c_str(), path_buf);
110
111         return subst(path_buf[0] ? path_buf : p, '\\', '/');
112 }
113
114
115 string convert_path_list(string const & p, PathStyle const & target)
116 {
117         char const * const pc = p.c_str();
118         PathStyle const actual = cygwin_posix_path_list_p(pc) ? posix : windows;
119
120         if (target != actual) {
121                 int const target_size = (target == posix) ?
122                                 cygwin_win32_to_posix_path_list_buf_size(pc) :
123                                 cygwin_posix_to_win32_path_list_buf_size(pc);
124
125                 char * ptr = new char[target_size];
126
127                 if (ptr) {
128                         if (target == posix)
129                                 cygwin_win32_to_posix_path_list(pc, ptr);
130                         else
131                                 cygwin_posix_to_win32_path_list(pc, ptr);
132
133                         string path_list = subst(ptr, '\\', '/');
134                         delete ptr;
135                         return path_list;
136                 }
137         }
138
139         return subst(p, '\\', '/');
140 }
141
142 } // namespace anon
143
144
145 string external_path(string const & p)
146 {
147         return convert_path(p, cygwin_path_fix_ ? PathStyle(windows)
148                                                 : PathStyle(posix));
149 }
150
151
152 string internal_path(string const & p)
153 {
154         return convert_path(p, PathStyle(posix));
155 }
156
157
158 string external_path_list(string const & p)
159 {
160         return convert_path_list(p, cygwin_path_fix_ ? PathStyle(windows)
161                                                      : PathStyle(posix));
162 }
163
164
165 string internal_path_list(string const & p)
166 {
167         return convert_path_list(p, PathStyle(posix));
168 }
169
170
171 string latex_path(string const & p)
172 {
173         // We may need a posix style path or a windows style path (depending
174         // on cygwin_path_fix_), but we use always forward slashes, since it
175         // gets written into a .tex file.
176
177         if (cygwin_path_fix_ && is_absolute_path(p)) {
178                 string dos_path = convert_path(p, PathStyle(windows));
179                 lyxerr[Debug::LATEX]
180                         << "<Cygwin path correction> ["
181                         << p << "]->>["
182                         << dos_path << ']' << endl;
183                 return dos_path;
184         }
185
186         return convert_path(p, PathStyle(posix));
187 }
188
189
190 bool is_absolute_path(string const & p)
191 {
192         if (p.empty())
193                 return false;
194
195         bool isDosPath = (p.length() > 1 && p[1] == ':');
196         bool isUnixPath = (p[0] == '/');
197
198         return isDosPath || isUnixPath;
199 }
200
201
202 // returns a string suitable to be passed to popen when
203 // reading a pipe
204 char const * popen_read_mode()
205 {
206         return "r";
207 }
208
209
210 string const & nulldev()
211 {
212         static string const nulldev_ = "/dev/null";
213         return nulldev_;
214 }
215
216
217 shell_type shell()
218 {
219         return UNIX;
220 }
221
222
223 char path_separator()
224 {
225         return ':';
226 }
227
228
229 void cygwin_path_fix(bool use_cygwin_paths)
230 {
231         cygwin_path_fix_ = use_cygwin_paths;
232 }
233
234 } // namespace os
235 } // namespace support
236 } // namespace lyx