Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  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. }
  408.