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