3 // Various OS specific functions
7 #pragma implementation "os.h"
11 #include "support/filetools.h"
12 #define INCL_DOSFILEMGR
13 #define INCL_DOSMODULEMGR
14 #define INCL_DOSPROCESS
16 #define INCL_DOSERRORS
24 os::shell_type shell_ = os::UNIX;
25 unsigned long cp_ = 0;
33 void init(int * argc, char ** argv[])
35 if (argc != 0 /* This is a hack! */) {
36 _wildcard(argc, argv);
37 PTIB ptib = new TIB[1];
38 PPIB ppib = new PIB[1];
39 APIRET rc = DosGetInfoBlocks(&ptib, &ppib);
42 char* tmp = new char[256];
43 // This is the only reliable way to retrieve the executable name.
44 rc = DosQueryModuleName(ppib->pib_hmte, 256L, tmp);
49 binname_ = OnlyFilename(p);
50 binname_.erase(binname_.length()-4, string::npos);
51 binpath_ = OnlyPath(p);
53 // OS/2 cmd.exe has another use for '&'
54 string sh = OnlyFilename(GetEnvPath("EMXSHELL"));
56 // COMSPEC is set, unless user unsets
57 sh = OnlyFilename(GetEnvPath("COMSPEC"));
61 sh = lowercase(sh); // DosMapCase() is an overkill here
62 if (contains(sh, "cmd.exe") || contains(sh, "4os2.exe"))
68 static bool initialized = false;
73 ULONG CPList[3] = {0};
75 APIRET rc = DosQueryCp(3 * sizeof(ULONG), CPList, &CPList_size);
78 // CPList[0] == process current codepage,
79 // CPList[1] == system default codepage, the rest are auxilary.
80 // Once cp_ is correctly set, you can call other routines.
85 void warn(string const & /*mesg*/)
96 rc = DosQueryCurrentDisk(&drv_num, &drv_map);
99 char drive = 'A' + drv_num -1;
100 string tmp(1, drive);
106 string::size_type common_path(string const & p1, string const & p2)
108 static bool initialized = false;
116 cntry.codepage = cp_;
117 string temp1 = slashify_path(p1);
118 string temp2 = slashify_path(p2);
119 char * tmp1 = const_cast<char *> (temp1.c_str());
120 char * tmp2 = const_cast<char *> (temp2.c_str());
121 /* rc = */ DosMapCase(p1.length(), &cntry, tmp1);
122 // if (rc != NO_ERROR)
124 /* rc = */ DosMapCase(p2.length(), &cntry, tmp2);
125 // if (rc != NO_ERROR)
127 // This algorithm works only if paths are slashified on DBCS systems.
128 string::size_type i = 0;
129 string::size_type p1_len = p1.length();
130 string::size_type p2_len = p2.length();
131 while (i < p1_len && i < p2_len && tmp1[i] == tmp2[i])
133 if ((i < p1_len && i < p2_len)
134 || (i < p1_len && tmp1[i] != '/' && i == p2_len)
135 || (i < p2_len && tmp2[i] != '/' && i == p1_len))
138 --i; // here was the last match
139 while (i && tmp1[i] != '/')
146 string slashify_path(string const & p)
148 static bool initialized = false;
149 static bool leadbyte[256] = {false};
154 cntry.codepage = cp_;
155 unsigned char *DBCSinfo = new unsigned char[12];
156 /* rc = */ DosQueryDBCSEnv(12, &cntry, (char*) DBCSinfo);
157 // if (rc != NO_ERROR)
159 for (int j = 1; j < 12; j += 2)
162 bool isLeadByte = false;
163 while (*DBCSinfo != 0) {
164 if (i == *DBCSinfo) {
165 isLeadByte = !isLeadByte;
168 leadbyte[i++] = isLeadByte;
172 string::iterator lit = p.begin();
173 string::iterator end = p.end();
174 for (; lit < end; ++lit) {
175 if (leadbyte[(*lit)])
180 p = subst(p, "//", "/");
185 string external_path(string const & p)
191 string internal_path(string const & p)
197 bool is_absolute_path(string const & p)
199 return (p.length() > 1
200 && isalpha(static_cast<unsigned char>(p[0]))
205 // returns a string suitable to be passed to popen when
207 char const * popen_read_mode()
225 void setTmpDir(string const & p)
242 } // end namespace os