Subversion Repositories pentevo

Rev

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
}