]> git.lyx.org Git - lyx.git/blob - src/support/os_os2.C
make "make distcheck" work
[lyx.git] / src / support / os_os2.C
1 /**
2  * \file os_os2.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  *
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/filetools.h"
17 #define INCL_DOSFILEMGR
18 #define INCL_DOSMODULEMGR
19 #define INCL_DOSPROCESS
20 #define INCL_DOSNLS
21 #define INCL_DOSERRORS
22 #include <os2.h>
23
24
25 namespace lyx {
26 namespace support {
27 namespace os {
28
29 namespace {
30
31 shell_type shell_ = UNIX;
32 unsigned long cp_ = 0;
33
34 }
35
36
37 void init(int argc, char * argv[])
38 {
39         _wildcard(&argc, &argv);
40         PTIB ptib = new TIB[1];
41         PPIB ppib = new PIB[1];
42         APIRET rc = DosGetInfoBlocks(&ptib, &ppib);
43         if (rc != NO_ERROR)
44                 exit(rc);
45
46         // OS/2 cmd.exe has another use for '&'
47         string sh = OnlyFilename(getEnvPath("EMXSHELL"));
48         if (sh.empty()) {
49                 // COMSPEC is set, unless user unsets
50                 sh = OnlyFilename(getEnvPath("COMSPEC"));
51                 if (sh.empty())
52                         sh = "cmd.exe";
53         }
54         sh = lowercase(sh);     // DosMapCase() is an overkill here
55         if (contains(sh, "cmd.exe") || contains(sh, "4os2.exe"))
56                 shell_ = os::CMD_EXE;
57         else
58                 shell_ = os::UNIX;
59
60         static bool initialized = false;
61         if (initialized)
62                 return;
63         initialized = true;
64
65         ULONG CPList[3] = {0};
66         ULONG CPList_size;
67         APIRET rc = DosQueryCp(3 * sizeof(ULONG), CPList, &CPList_size);
68         if (rc != NO_ERROR)
69                 exit(rc);
70         // CPList[0] == process current codepage,
71         // CPList[1] == system default codepage, the rest are auxilary.
72         // Once cp_ is correctly set, you can call other routines.
73         cp_ = CPList[1];
74 }
75
76
77 string current_root()
78 {
79         APIRET rc;
80         ULONG drv_num;
81         ULONG drv_map;
82         rc = DosQueryCurrentDisk(&drv_num, &drv_map);
83         if (rc != NO_ERROR)
84                 exit(rc);
85         char drive = 'A' + drv_num -1;
86         string tmp(1, drive);
87         tmp  += ":/";
88         return tmp;
89 }
90
91
92 string::size_type common_path(string const & p1, string const & p2)
93 {
94         static bool initialized = false;
95         if (!initialized) {
96                 init(0, 0);
97                 initialized = true;
98         }
99
100         COUNTRYCODE cntry;
101         cntry.country = 0;
102         cntry.codepage = cp_;
103         string temp1 = internal_path(p1);
104         string temp2 = internal_path(p2);
105         char * tmp1 = const_cast<char *> (temp1.c_str());
106         char * tmp2 = const_cast<char *> (temp2.c_str());
107         /* rc = */ DosMapCase(p1.length(), &cntry, tmp1);
108         // if (rc != NO_ERROR)
109         //      exit(rc);
110         /* rc = */ DosMapCase(p2.length(), &cntry, tmp2);
111         // if (rc != NO_ERROR)
112         //      exit(rc);
113         // This algorithm works only if paths are slashified on DBCS systems.
114         string::size_type i = 0;
115         string::size_type p1_len = p1.length();
116         string::size_type p2_len = p2.length();
117         while (i < p1_len && i < p2_len && tmp1[i] == tmp2[i])
118                 ++i;
119         if ((i < p1_len && i < p2_len)
120             || (i < p1_len && tmp1[i] != '/' && i == p2_len)
121             || (i < p2_len && tmp2[i] != '/' && i == p1_len))
122         {
123                 if (i)
124                         --i;     // here was the last match
125                 while (i && tmp1[i] != '/')
126                         --i;
127         }
128         return i;
129 }
130
131
132 string internal_path(string const & p)
133 {
134         static bool initialized = false;
135         static bool leadbyte[256] = {false};
136         if (!initialized) {
137                 init(0, 0);
138                 COUNTRYCODE cntry;
139                 cntry.country = 0;
140                 cntry.codepage = cp_;
141                 unsigned char *DBCSinfo = new unsigned char[12];
142                 /* rc = */ DosQueryDBCSEnv(12, &cntry, (char*) DBCSinfo);
143                 // if (rc != NO_ERROR)
144                 //      exit(rc);
145                 for (int j = 1; j < 12; j += 2)
146                         DBCSinfo[j]++;
147                 unsigned char i = 0;
148                 bool isLeadByte = false;
149                 while (*DBCSinfo != 0) {
150                         if (i == *DBCSinfo) {
151                                 isLeadByte = !isLeadByte;
152                                 DBCSinfo++;
153                         }
154                         leadbyte[i++] = isLeadByte;
155                 }
156                 initialized = true;
157         }
158         string::iterator lit = p.begin();
159         string::iterator end = p.end();
160         for (; lit < end; ++lit) {
161                 if (leadbyte[(*lit)])
162                         lit += 2;
163                 if ((*lit) == '\\')
164                         (*lit) = '/';
165         }
166         p = subst(p, "//", "/");
167         return p;
168 }
169
170
171 string external_path(string const & p)
172 {
173         return p;
174 }
175
176
177 bool is_absolute_path(string const & p)
178 {
179         return (p.length() > 1
180                 && isalpha(static_cast<unsigned char>(p[0]))
181                 && p[1] == ':');
182 }
183
184
185 // returns a string suitable to be passed to popen when
186 // reading a pipe
187 char const * popen_read_mode()
188 {
189         return "r";
190 }
191
192
193 string const & nulldev()
194 {
195         static string const nulldev_ = "null";
196         return nulldev_;
197 }
198
199
200 shell_type shell()
201 {
202         return shell_;
203 }
204
205
206 char path_separator()
207 {
208         return ';';
209 }
210
211
212 void cygwin_path_fix(bool)
213 {}
214
215 } // namespace os
216 } // namespace support
217 } // namespace lyx