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