3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Ruurd A. Reitsma
8 * Full author contact details are available in file CREDITS.
10 * Various OS specific functions
15 #include "support/os.h"
16 #include "support/filetools.h"
17 #define INCL_DOSFILEMGR
18 #define INCL_DOSMODULEMGR
19 #define INCL_DOSPROCESS
21 #define INCL_DOSERRORS
24 #include <boost/scoped_array.hpp>
26 using boost::scoped_array;
36 os::shell_type shell_ = os::UNIX;
37 unsigned long cp_ = 0;
45 void init(int argc, char * argv[])
47 _wildcard(&argc, &argv);
48 PTIB ptib = new TIB[1];
49 PPIB ppib = new PIB[1];
50 APIRET rc = DosGetInfoBlocks(&ptib, &ppib);
53 scoped_array<char> tmp(new char[256]);
54 // This is the only reliable way to retrieve the executable name.
55 rc = DosQueryModuleName(ppib->pib_hmte, 256L, tmp);
60 binname_ = OnlyFilename(p);
61 binname_.erase(binname_.length()-4, string::npos);
62 binpath_ = OnlyPath(p);
64 // OS/2 cmd.exe has another use for '&'
65 string sh = OnlyFilename(GetEnvPath("EMXSHELL"));
67 // COMSPEC is set, unless user unsets
68 sh = OnlyFilename(GetEnvPath("COMSPEC"));
72 sh = lowercase(sh); // DosMapCase() is an overkill here
73 if (contains(sh, "cmd.exe") || contains(sh, "4os2.exe"))
78 static bool initialized = false;
83 ULONG CPList[3] = {0};
85 APIRET rc = DosQueryCp(3 * sizeof(ULONG), CPList, &CPList_size);
88 // CPList[0] == process current codepage,
89 // CPList[1] == system default codepage, the rest are auxilary.
90 // Once cp_ is correctly set, you can call other routines.
94 homepath_ = GetEnvPath("HOME");
99 void warn(string const & /*mesg*/)
105 string current_root()
110 rc = DosQueryCurrentDisk(&drv_num, &drv_map);
113 char drive = 'A' + drv_num -1;
114 string tmp(1, drive);
120 string::size_type common_path(string const & p1, string const & p2)
122 static bool initialized = false;
130 cntry.codepage = cp_;
131 string temp1 = slashify_path(p1);
132 string temp2 = slashify_path(p2);
133 char * tmp1 = const_cast<char *> (temp1.c_str());
134 char * tmp2 = const_cast<char *> (temp2.c_str());
135 /* rc = */ DosMapCase(p1.length(), &cntry, tmp1);
136 // if (rc != NO_ERROR)
138 /* rc = */ DosMapCase(p2.length(), &cntry, tmp2);
139 // if (rc != NO_ERROR)
141 // This algorithm works only if paths are slashified on DBCS systems.
142 string::size_type i = 0;
143 string::size_type p1_len = p1.length();
144 string::size_type p2_len = p2.length();
145 while (i < p1_len && i < p2_len && tmp1[i] == tmp2[i])
147 if ((i < p1_len && i < p2_len)
148 || (i < p1_len && tmp1[i] != '/' && i == p2_len)
149 || (i < p2_len && tmp2[i] != '/' && i == p1_len))
152 --i; // here was the last match
153 while (i && tmp1[i] != '/')
160 string slashify_path(string const & p)
162 static bool initialized = false;
163 static bool leadbyte[256] = {false};
168 cntry.codepage = cp_;
169 unsigned char *DBCSinfo = new unsigned char[12];
170 /* rc = */ DosQueryDBCSEnv(12, &cntry, (char*) DBCSinfo);
171 // if (rc != NO_ERROR)
173 for (int j = 1; j < 12; j += 2)
176 bool isLeadByte = false;
177 while (*DBCSinfo != 0) {
178 if (i == *DBCSinfo) {
179 isLeadByte = !isLeadByte;
182 leadbyte[i++] = isLeadByte;
186 string::iterator lit = p.begin();
187 string::iterator end = p.end();
188 for (; lit < end; ++lit) {
189 if (leadbyte[(*lit)])
194 p = subst(p, "//", "/");
199 string external_path(string const & p)
205 string internal_path(string const & p)
211 bool is_absolute_path(string const & p)
213 return (p.length() > 1
214 && isalpha(static_cast<unsigned char>(p[0]))
219 // returns a string suitable to be passed to popen when
221 char const * popen_read_mode()
227 string const & binpath()
233 string const & binname()
239 void setTmpDir(string const & p)
245 string const & getTmpDir()
251 string const & homepath()
257 string const & nulldev()
268 } // end namespace os