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