Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1186 | savelij | 1 | /* bpemu.c */ |
2 | /*****************************************************************************/ |
||
3 | /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */ |
||
4 | /* */ |
||
5 | /* AS-Portierung */ |
||
6 | /* */ |
||
7 | /* Emulation einiger Borland-Pascal-Funktionen */ |
||
8 | /* */ |
||
9 | /*****************************************************************************/ |
||
10 | |||
11 | #include "stdinc.h" |
||
12 | #include <string.h> |
||
13 | #include <sys/types.h> |
||
14 | #include <sys/stat.h> |
||
15 | #include <ctype.h> |
||
16 | |||
17 | #include "strutil.h" |
||
18 | #include "bpemu.h" |
||
19 | |||
20 | #ifdef __MSDOS__ |
||
21 | #include <dos.h> |
||
22 | #include <dir.h> |
||
23 | #endif |
||
24 | |||
25 | #if defined( __EMX__ ) || defined( __IBMC__ ) |
||
26 | #include <os2.h> |
||
27 | #endif |
||
28 | |||
29 | #ifdef __MINGW32__ |
||
30 | #include <direct.h> |
||
31 | #endif |
||
32 | |||
33 | char *FExpand(char *Src) |
||
34 | { |
||
35 | static String CurrentDir; |
||
36 | String Copy; |
||
37 | #ifdef DRSEP |
||
38 | String DrvPart; |
||
39 | #endif /* DRSEP */ |
||
40 | char *p, *p2; |
||
41 | |||
42 | strmaxcpy(Copy, Src, STRINGSIZE); |
||
43 | |||
44 | #ifdef DRSEP |
||
45 | p = strchr(Copy,DRSEP); |
||
46 | if (p) |
||
47 | { |
||
48 | memcpy(DrvPart, Copy, p - Copy); |
||
49 | DrvPart[p - Copy] = '\0'; |
||
50 | strmov(Copy, p + 1); |
||
51 | } |
||
52 | else |
||
53 | *DrvPart = '\0'; |
||
54 | #endif |
||
55 | |||
56 | #if (defined __MSDOS__) |
||
57 | { |
||
58 | int DrvNum; |
||
59 | |||
60 | if (*DrvPart == '\0') |
||
61 | { |
||
62 | DrvNum = getdisk(); |
||
63 | *DrvPart = DrvNum + 'A'; |
||
64 | DrvPart[1] = '\0'; |
||
65 | DrvNum++; |
||
66 | } |
||
67 | else |
||
68 | DrvNum = toupper(*DrvPart) - '@'; |
||
69 | getcurdir(DrvNum, CurrentDir); |
||
70 | } |
||
71 | #elif (defined __EMX__) || (defined __IBMC__) |
||
72 | { |
||
73 | ULONG DrvNum, Dummy; |
||
74 | |||
75 | if (*DrvPart == '\0') |
||
76 | { |
||
77 | DosQueryCurrentDisk(&DrvNum, &Dummy); |
||
78 | *DrvPart = DrvNum + '@'; |
||
79 | DrvPart[1] = '\0'; |
||
80 | } |
||
81 | else |
||
82 | DrvNum = toupper(*DrvPart) - '@'; |
||
83 | Dummy = 255; |
||
84 | DosQueryCurrentDir(DrvNum, (PBYTE) CurrentDir, &Dummy); |
||
85 | } |
||
86 | #elif (defined __MINGW32__) |
||
87 | { |
||
88 | int DrvNum; |
||
89 | |||
90 | if (!*DrvPart) |
||
91 | { |
||
92 | DrvNum = _getdrive(); |
||
93 | *DrvPart = DrvNum + '@'; |
||
94 | DrvPart[1] = '\0'; |
||
95 | } |
||
96 | else |
||
97 | DrvNum = toupper(*DrvPart) - '@'; |
||
98 | _getdcwd(DrvNum, CurrentDir, STRINGSIZE); |
||
99 | if (CurrentDir[1] == ':') |
||
100 | strmov(CurrentDir, CurrentDir + 2); |
||
101 | } |
||
102 | #elif (defined _WIN32) /* CygWIN */ |
||
103 | if (!getcwd(CurrentDir, STRINGSIZE)) |
||
104 | 0[CurrentDir] = '\0'; |
||
105 | for (p = CurrentDir; *p; p++) |
||
106 | if (*p == '/') *p = '\\'; |
||
107 | #else /* UNIX */ |
||
108 | if (!getcwd(CurrentDir, STRINGSIZE)) |
||
109 | 0[CurrentDir] = '\0'; |
||
110 | #endif |
||
111 | |||
112 | if ((*CurrentDir) && (CurrentDir[strlen(CurrentDir) - 1] != PATHSEP)) |
||
113 | strmaxcat(CurrentDir, SPATHSEP, STRINGSIZE); |
||
114 | if (*CurrentDir!=PATHSEP) |
||
115 | strmaxprep(CurrentDir, SPATHSEP, STRINGSIZE); |
||
116 | |||
117 | if (*Copy == PATHSEP) |
||
118 | { |
||
119 | strmaxcpy(CurrentDir, SPATHSEP, STRINGSIZE); |
||
120 | strmov(Copy, Copy + 1); |
||
121 | } |
||
122 | |||
123 | #ifdef DRSEP |
||
124 | #ifdef __CYGWIN32__ |
||
125 | /* win32 getcwd() does not deliver current drive letter, therefore only prepend a drive letter |
||
126 | if there was one before. */ |
||
127 | if (*DrvPart) |
||
128 | #endif |
||
129 | { |
||
130 | strmaxprep(CurrentDir, SDRSEP, STRINGSIZE); |
||
131 | strmaxprep(CurrentDir, DrvPart, STRINGSIZE); |
||
132 | } |
||
133 | #endif |
||
134 | |||
135 | while (True) |
||
136 | { |
||
137 | p = strchr(Copy, PATHSEP); |
||
138 | if (!p) |
||
139 | break; |
||
140 | *p = '\0'; |
||
141 | if (!strcmp(Copy, ".")); |
||
142 | else if ((!strcmp(Copy, "..")) && (strlen(CurrentDir) > 1)) |
||
143 | { |
||
144 | CurrentDir[strlen(CurrentDir) - 1] = '\0'; |
||
145 | p2 = strrchr(CurrentDir, PATHSEP); p2[1] = '\0'; |
||
146 | } |
||
147 | else |
||
148 | { |
||
149 | strmaxcat(CurrentDir, Copy, STRINGSIZE); |
||
150 | strmaxcat(CurrentDir, SPATHSEP, STRINGSIZE); |
||
151 | } |
||
152 | strmov(Copy, p + 1); |
||
153 | } |
||
154 | |||
155 | strmaxcat(CurrentDir, Copy, STRINGSIZE); |
||
156 | |||
157 | return CurrentDir; |
||
158 | } |
||
159 | |||
160 | /*!------------------------------------------------------------------------ |
||
161 | * \fn FSearch(char *pDest, size_t DestSize, const char *pFileToSearch, const char *pCurrFileName, const char *pSearchPath) |
||
162 | * \brief search for file in given path(s) |
||
163 | * \param pDest where to put result |
||
164 | * \param DestSize size of result buffer |
||
165 | * \param pFileToSearch file to search for |
||
166 | * \param pCurrFileName file this file was referenced from |
||
167 | * \param pSearchPath list of directories to search |
||
168 | * \return 0 if found or error code |
||
169 | * ------------------------------------------------------------------------ */ |
||
170 | |||
171 | static int AssembleAndCheck(char *pDest, size_t DestSize, const char *pPath, unsigned PathLen, const char *pFileToSearch) |
||
172 | { |
||
173 | FILE *pDummy; |
||
174 | |||
175 | if (PathLen > DestSize - 1) |
||
176 | PathLen = DestSize - 1; |
||
177 | memcpy(pDest, pPath, PathLen); |
||
178 | pDest[PathLen] = '\0'; |
||
179 | #ifdef __CYGWIN32__ |
||
180 | DeCygwinPath(pDest); |
||
181 | #endif |
||
182 | if (PathLen > 0) |
||
183 | strmaxcat(pDest, SPATHSEP, DestSize); |
||
184 | strmaxcat(pDest, pFileToSearch, DestSize); |
||
185 | pDummy = fopen(pDest, "r"); |
||
186 | if (pDummy) |
||
187 | { |
||
188 | fclose(pDummy); |
||
189 | return 0; |
||
190 | } |
||
191 | else |
||
192 | return 2; |
||
193 | } |
||
194 | |||
195 | int FSearch(char *pDest, size_t DestSize, const char *pFileToSearch, const char *pCurrFileName, const char *pSearchPath) |
||
196 | { |
||
197 | /* If the file has an absolute path ('/....', '\....', 'X:....'), do not search relative |
||
198 | to current file's directory: */ |
||
199 | |||
200 | Boolean Absolute = (*pFileToSearch == '/'); |
||
201 | const char *pPos, *pStart; |
||
202 | |||
203 | #if (defined _WIN32) || (defined __EMX__) || (defined __IBMC__) || (defined __MSDOS__) |
||
204 | if (*pFileToSearch == PATHSEP) |
||
205 | Absolute = True; |
||
206 | #endif |
||
207 | #ifdef DRSEP |
||
208 | if ((as_islower(*pFileToSearch) || as_isupper(*pFileToSearch)) |
||
209 | && (pFileToSearch[1] == DRSEP)) |
||
210 | Absolute = True; |
||
211 | #endif |
||
212 | |||
213 | if (pCurrFileName && !Absolute) |
||
214 | { |
||
215 | #if (defined _WIN32) || (defined __EMX__) || (defined __IBMC__) || (defined __MSDOS__) |
||
216 | /* On systems with \ as path separator, we may get a mixture of / and \ in the path. |
||
217 | Assure we find the last one of either: */ |
||
218 | |||
219 | pPos = strrmultchr(pCurrFileName, SPATHSEP "/"); |
||
220 | #else |
||
221 | pPos = strrchr(pCurrFileName, PATHSEP); |
||
222 | #endif |
||
223 | if (!AssembleAndCheck(pDest, DestSize, pCurrFileName, pPos ? pPos - pCurrFileName : 0, pFileToSearch)) |
||
224 | return 0; |
||
225 | } |
||
226 | else |
||
227 | { |
||
228 | if (!AssembleAndCheck(pDest, DestSize, NULL, 0, pFileToSearch)) |
||
229 | return 0; |
||
230 | } |
||
231 | |||
232 | /* TODO: if the file has an absolute path, searching the include path should be pointless: */ |
||
233 | |||
234 | pStart = pSearchPath; |
||
235 | while (True) |
||
236 | { |
||
237 | pPos = strchr(pStart, DIRSEP); |
||
238 | |||
239 | if (!AssembleAndCheck(pDest, DestSize, pStart, pPos ? pPos - pStart : (int)strlen(pStart), pFileToSearch)) |
||
240 | return 0; |
||
241 | if (pPos) |
||
242 | pStart = pPos+ 1; |
||
243 | else |
||
244 | break; |
||
245 | } |
||
246 | |||
247 | *pDest = '\0'; |
||
248 | return 2; |
||
249 | } |
||
250 | |||
251 | long FileSize(FILE *file) |
||
252 | { |
||
253 | long Save = ftell(file), Size; |
||
254 | |||
255 | fseek(file, 0, SEEK_END); |
||
256 | Size=ftell(file); |
||
257 | fseek(file, Save, SEEK_SET); |
||
258 | return Size; |
||
259 | } |
||
260 | |||
261 | Byte Lo(Word inp) |
||
262 | { |
||
263 | return (inp & 0xff); |
||
264 | } |
||
265 | |||
266 | Byte Hi(Word inp) |
||
267 | { |
||
268 | return ((inp >> 8) & 0xff); |
||
269 | } |
||
270 | |||
271 | unsigned LoWord(LongWord Src) |
||
272 | { |
||
273 | return (Src & 0xffff); |
||
274 | } |
||
275 | |||
276 | unsigned HiWord(LongWord Src) |
||
277 | { |
||
278 | return ((Src >> 16) & 0xffff); |
||
279 | } |
||
280 | |||
281 | unsigned long LoDWord(LargeWord Src) |
||
282 | { |
||
283 | return Src & 0xfffffffful; |
||
284 | } |
||
285 | |||
286 | Boolean Odd(int inp) |
||
287 | { |
||
288 | return ((inp & 1) == 1); |
||
289 | } |
||
290 | |||
291 | Boolean DirScan(const char *Mask, charcallback callback) |
||
292 | { |
||
293 | char Name[1024]; |
||
294 | |||
295 | #ifdef __MSDOS__ |
||
296 | struct ffblk blk; |
||
297 | int res; |
||
298 | const char *pos; |
||
299 | |||
300 | res = findfirst(Mask, &blk, FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_LABEL | FA_DIREC | FA_ARCH); |
||
301 | if (res < 0) |
||
302 | return False; |
||
303 | pos = strrchr(Mask, PATHSEP); |
||
304 | if (!pos) |
||
305 | pos = strrchr(Mask, DRSEP); |
||
306 | pos = pos ? pos + 1 : Mask; |
||
307 | memcpy(Name, Mask, pos - Mask); |
||
308 | while (res==0) |
||
309 | { |
||
310 | if ((blk.ff_attrib & (FA_LABEL|FA_DIREC)) == 0) |
||
311 | { |
||
312 | strcpy(Name + (pos - Mask), blk.ff_name); |
||
313 | callback(Name); |
||
314 | } |
||
315 | res = findnext(&blk); |
||
316 | } |
||
317 | return True; |
||
318 | #else |
||
319 | #if defined ( __EMX__ ) || defined ( __IBMC__ ) |
||
320 | HDIR hdir = 1; |
||
321 | FILEFINDBUF3 buf; |
||
322 | ULONG rescnt; |
||
323 | USHORT res; |
||
324 | char *pos; |
||
325 | |||
326 | rescnt = 1; |
||
327 | res = DosFindFirst(Mask, &hdir, 0x16, &buf, sizeof(buf), &rescnt, 1); |
||
328 | if (res) |
||
329 | return False; |
||
330 | pos = strrchr(Mask, PATHSEP); |
||
331 | if (!pos) |
||
332 | pos = strrchr(Mask, DRSEP); |
||
333 | pos = pos ? pos + 1 : Mask; |
||
334 | memcpy(Name, Mask, pos - Mask); |
||
335 | while (res == 0) |
||
336 | { |
||
337 | strcpy(Name + (pos - Mask), buf.achName); |
||
338 | callback(Name); |
||
339 | res = DosFindNext(hdir, &buf, sizeof(buf), &rescnt); |
||
340 | } |
||
341 | return True; |
||
342 | #else |
||
343 | strmaxcpy(Name, Mask, sizeof(Name)); |
||
344 | callback(Name); |
||
345 | return True; |
||
346 | #endif |
||
347 | #endif |
||
348 | } |
||
349 | |||
350 | LongInt MyGetFileTime(char *Name) |
||
351 | { |
||
352 | struct stat st; |
||
353 | |||
354 | if (stat(Name, &st) == -1) |
||
355 | return 0; |
||
356 | else |
||
357 | return st.st_mtime; |
||
358 | } |
||
359 | |||
360 | #ifdef __CYGWIN32__ |
||
361 | |||
362 | /* convert CygWin-style paths back to something usable by other Win32 apps */ |
||
363 | |||
364 | char *DeCygWinDirList(char *pStr) |
||
365 | { |
||
366 | char *pRun; |
||
367 | |||
368 | for (pRun = pStr; *pRun; pRun++) |
||
369 | if (*pRun == ':') |
||
370 | *pRun = ';'; |
||
371 | |||
372 | return pStr; |
||
373 | } |
||
374 | |||
375 | char *DeCygwinPath(char *pStr) |
||
376 | { |
||
377 | char *pRun; |
||
378 | |||
379 | if ((strlen(pStr) >= 4) |
||
380 | && (pStr[0] =='/') && (pStr[1] == '/') && (pStr[3] == '/') |
||
381 | && (isalpha(pStr[2]))) |
||
382 | { |
||
383 | strmov(pStr, pStr + 1); |
||
384 | pStr[0] = pStr[1]; |
||
385 | pStr[1] = ':'; |
||
386 | } |
||
387 | |||
388 | if ((strlen(pStr) >= 4) |
||
389 | && (pStr[0] =='\\') && (pStr[1] == '\\') && (pStr[3] == '\\') |
||
390 | && (isalpha(pStr[2]))) |
||
391 | { |
||
392 | strmov(pStr, pStr + 1); |
||
393 | pStr[0] = pStr[1]; |
||
394 | pStr[1] = ':'; |
||
395 | } |
||
396 | |||
397 | for (pRun = pStr; *pRun; pRun++) |
||
398 | if (*pRun == '/') |
||
399 | *pRun = '\\'; |
||
400 | |||
401 | return pStr; |
||
402 | } |
||
403 | #endif /* __CYGWIN32__ */ |
||
404 | |||
405 | void bpemu_init(void) |
||
406 | { |
||
407 | } |