2006-04-23 06:44:19 +00:00
|
|
|
/*
|
|
|
|
* Playing-field leveller for Build
|
|
|
|
* by Jonathon Fowler
|
|
|
|
*
|
|
|
|
* A note about this:
|
|
|
|
* 1. There is some kind of problem somewhere in the functions below because
|
|
|
|
* compiling with __compat_h_macrodef__ disabled makes stupid things happen.
|
|
|
|
* 2. The functions below, aside from the ones which aren't trivial, were never
|
|
|
|
* really intended to be used for anything except tracking anr removing ties
|
|
|
|
* to the standard C library from games. Using the Bxx versions of functions
|
|
|
|
* means we can redefine those names to link up with different runtime library
|
|
|
|
* names.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
|
#define _WIN32_IE 0x0400
|
|
|
|
#include <windows.h>
|
|
|
|
#include <shlobj.h>
|
2006-11-19 03:02:36 +00:00
|
|
|
#include <direct.h>
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
2006-07-01 01:40:18 +00:00
|
|
|
#ifdef __APPLE__
|
2008-08-20 22:58:09 +00:00
|
|
|
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_3
|
2006-07-01 01:40:18 +00:00
|
|
|
# include <CoreFoundation/CoreFoundation.h>
|
|
|
|
# include <CoreServices/CoreServices.h>
|
|
|
|
#endif
|
2008-08-20 22:58:09 +00:00
|
|
|
#endif
|
2006-07-01 01:40:18 +00:00
|
|
|
|
2006-04-23 06:44:19 +00:00
|
|
|
#if defined(__WATCOMC__)
|
|
|
|
# include <direct.h>
|
|
|
|
#elif defined(_MSC_VER)
|
|
|
|
# include <io.h>
|
|
|
|
#else
|
|
|
|
# include <dirent.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "compat.h"
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef __compat_h_macrodef__
|
|
|
|
|
|
|
|
int Brand(void)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return rand();
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *Bmalloc(bsize_t size)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return malloc(size);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Bfree(void *ptr)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
free(ptr);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bopen(const char *pathname, int flags, unsigned mode)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
int n=0,o=0;
|
|
|
|
|
|
|
|
if (flags&BO_BINARY) n|=O_BINARY; else n|=O_TEXT;
|
|
|
|
if ((flags&BO_RDWR)==BO_RDWR) n|=O_RDWR;
|
|
|
|
else if ((flags&BO_RDWR)==BO_WRONLY) n|=O_WRONLY;
|
|
|
|
else if ((flags&BO_RDWR)==BO_RDONLY) n|=O_RDONLY;
|
|
|
|
if (flags&BO_APPEND) n|=O_APPEND;
|
|
|
|
if (flags&BO_CREAT) n|=O_CREAT;
|
|
|
|
if (flags&BO_TRUNC) n|=O_TRUNC;
|
|
|
|
if (mode&BS_IREAD) o|=S_IREAD;
|
|
|
|
if (mode&BS_IWRITE) o|=S_IWRITE;
|
|
|
|
if (mode&BS_IEXEC) o|=S_IEXEC;
|
|
|
|
|
|
|
|
return open(pathname,n,o);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bclose(int fd)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return close(fd);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bssize_t Bwrite(int fd, const void *buf, bsize_t count)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return write(fd,buf,count);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bssize_t Bread(int fd, void *buf, bsize_t count)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return read(fd,buf,count);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Blseek(int fildes, int offset, int whence)
|
|
|
|
{
|
2007-12-12 17:42:14 +00:00
|
|
|
switch (whence)
|
|
|
|
{
|
2006-11-13 23:12:47 +00:00
|
|
|
case BSEEK_SET:
|
|
|
|
whence=SEEK_SET; break;
|
|
|
|
case BSEEK_CUR:
|
|
|
|
whence=SEEK_CUR; break;
|
|
|
|
case BSEEK_END:
|
|
|
|
whence=SEEK_END; break;
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
return lseek(fildes,offset,whence);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BFILE *Bfopen(const char *path, const char *mode)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return (BFILE*)fopen(path,mode);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bfclose(BFILE *stream)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return fclose((FILE*)stream);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Brewind(BFILE *stream)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
rewind((FILE*)stream);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bfgetc(BFILE *stream)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return fgetc((FILE*)stream);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *Bfgets(char *s, int size, BFILE *stream)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return fgets(s,size,(FILE*)stream);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bfputc(int c, BFILE *stream)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return fputc(c,(FILE*)stream);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bfputs(const char *s, BFILE *stream)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return fputs(s,(FILE*)stream);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bsize_t Bfread(void *ptr, bsize_t size, bsize_t nmemb, BFILE *stream)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return fread(ptr,size,nmemb,(FILE*)stream);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bsize_t Bfwrite(const void *ptr, bsize_t size, bsize_t nmemb, BFILE *stream)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return fwrite(ptr,size,nmemb,(FILE*)stream);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char *Bstrdup(const char *s)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return strdup(s);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *Bstrcpy(char *dest, const char *src)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return strcpy(dest,src);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *Bstrncpy(char *dest, const char *src, bsize_t n)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return strncpy(dest,src,n);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bstrcmp(const char *s1, const char *s2)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return strcmp(s1,s2);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bstrncmp(const char *s1, const char *s2, bsize_t n)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return strncmp(s1,s2,n);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bstrcasecmp(const char *s1, const char *s2)
|
|
|
|
{
|
|
|
|
#ifdef _MSC_VER
|
2006-04-24 19:04:22 +00:00
|
|
|
return stricmp(s1,s2);
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
return strcasecmp(s1,s2);
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int Bstrncasecmp(const char *s1, const char *s2, bsize_t n)
|
|
|
|
{
|
|
|
|
#ifdef _MSC_VER
|
2006-04-24 19:04:22 +00:00
|
|
|
return strnicmp(s1,s2,n);
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
return strncasecmp(s1,s2,n);
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
char *Bstrcat(char *dest, const char *src)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return strcat(dest,src);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *Bstrncat(char *dest, const char *src, bsize_t n)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return strncat(dest,src,n);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bsize_t Bstrlen(const char *s)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return strlen(s);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *Bstrchr(const char *s, int c)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return strchr(s,c);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *Bstrrchr(const char *s, int c)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return strrchr(s,c);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Batoi(const char *nptr)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return atoi(nptr);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
2007-12-12 17:42:14 +00:00
|
|
|
int Batol(const char *nptr)
|
2006-04-23 06:44:19 +00:00
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return atol(nptr);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
2007-12-12 17:42:14 +00:00
|
|
|
int int Bstrtol(const char *nptr, char **endptr, int base)
|
2006-04-23 06:44:19 +00:00
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return strtol(nptr,endptr,base);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
2007-12-12 17:42:14 +00:00
|
|
|
unsigned int int Bstrtoul(const char *nptr, char **endptr, int base)
|
2006-04-23 06:44:19 +00:00
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return strtoul(nptr,endptr,base);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *Bmemcpy(void *dest, const void *src, bsize_t n)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return memcpy(dest,src,n);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *Bmemmove(void *dest, const void *src, bsize_t n)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return memmove(dest,src,n);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *Bmemchr(const void *s, int c, bsize_t n)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return memchr(s,c,n);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *Bmemset(void *s, int c, bsize_t n)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return memset(s,c,n);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bprintf(const char *format, ...)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
va_list ap;
|
|
|
|
int r;
|
2006-04-23 06:44:19 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
va_start(ap,format);
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _MSC_VER
|
2006-04-24 19:04:22 +00:00
|
|
|
r = _vprintf(format,ap);
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
r = vprintf(format,ap);
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
va_end(ap);
|
|
|
|
return r;
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bsprintf(char *str, const char *format, ...)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
va_list ap;
|
|
|
|
int r;
|
2006-04-23 06:44:19 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
va_start(ap,format);
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _MSC_VER
|
2006-04-24 19:04:22 +00:00
|
|
|
r = _vsprintf(str,format,ap);
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
r = vsprintf(str,format,ap);
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
va_end(ap);
|
|
|
|
return r;
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bsnprintf(char *str, bsize_t size, const char *format, ...)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
va_list ap;
|
|
|
|
int r;
|
2006-04-23 06:44:19 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
va_start(ap,format);
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _MSC_VER
|
2006-04-24 19:04:22 +00:00
|
|
|
r = _vsnprintf(str,size,format,ap);
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
r = vsnprintf(str,size,format,ap);
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
va_end(ap);
|
|
|
|
return r;
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bvsnprintf(char *str, bsize_t size, const char *format, va_list ap)
|
|
|
|
{
|
|
|
|
#ifdef _MSC_VER
|
2006-04-24 19:04:22 +00:00
|
|
|
return _vsnprintf(str,size,format,ap);
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
return vsnprintf(str,size,format,ap);
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
char *Bgetenv(const char *name)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return getenv(name);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *Bgetcwd(char *buf, bsize_t size)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
return getcwd(buf,size);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // __compat_h_macrodef__
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Stuff which must be a function
|
|
|
|
//
|
|
|
|
|
|
|
|
char *Bgethomedir(void)
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
2008-03-07 21:59:10 +00:00
|
|
|
FARPROC aSHGetSpecialFolderPathA;
|
2006-04-24 19:04:22 +00:00
|
|
|
TCHAR appdata[MAX_PATH];
|
2008-08-23 03:12:23 +00:00
|
|
|
int loaded = 0;
|
|
|
|
HMODULE hShell32 = GetModuleHandle("shell32.dll");
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2008-08-23 03:12:23 +00:00
|
|
|
if (hShell32 == NULL)
|
|
|
|
{
|
|
|
|
hShell32 = LoadLibrary("shell32.dll");
|
|
|
|
loaded = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hShell32 == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
aSHGetSpecialFolderPathA = GetProcAddress(hShell32, "SHGetSpecialFolderPathA");
|
2008-03-07 21:59:10 +00:00
|
|
|
if (aSHGetSpecialFolderPathA != NULL)
|
|
|
|
if (SUCCEEDED(aSHGetSpecialFolderPathA(NULL, appdata, CSIDL_APPDATA, FALSE)))
|
2008-08-23 03:12:23 +00:00
|
|
|
{
|
|
|
|
if (loaded)
|
|
|
|
FreeLibrary(hShell32);
|
2008-03-07 21:59:10 +00:00
|
|
|
return strdup(appdata);
|
2008-08-23 03:12:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (loaded)
|
|
|
|
FreeLibrary(hShell32);
|
2006-04-24 19:04:22 +00:00
|
|
|
return NULL;
|
2008-08-20 22:58:09 +00:00
|
|
|
#elif defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_3
|
2006-07-01 01:40:18 +00:00
|
|
|
FSRef ref;
|
|
|
|
CFStringRef str;
|
|
|
|
CFURLRef base;
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
if (FSFindFolder(kUserDomain, kVolumeRootFolderType, kDontCreateFolder, &ref) < 0) return NULL;
|
|
|
|
base = CFURLCreateFromFSRef(NULL, &ref);
|
|
|
|
if (!base) return NULL;
|
|
|
|
str = CFURLCopyFileSystemPath(base, kCFURLPOSIXPathStyle);
|
|
|
|
CFRelease(base);
|
|
|
|
if (!str) return NULL;
|
|
|
|
s = (char*)CFStringGetCStringPtr(str,CFStringGetSystemEncoding());
|
|
|
|
if (s) s = strdup(s);
|
|
|
|
CFRelease(str);
|
|
|
|
return s;
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
char *e = getenv("HOME");
|
|
|
|
if (!e) return NULL;
|
|
|
|
return strdup(e);
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2006-07-01 01:40:18 +00:00
|
|
|
char *Bgetsupportdir(int global)
|
|
|
|
{
|
2008-08-20 22:58:09 +00:00
|
|
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3_
|
2008-03-22 10:23:57 +00:00
|
|
|
UNREFERENCED_PARAMETER(global);
|
2006-07-01 01:40:18 +00:00
|
|
|
return Bgethomedir();
|
|
|
|
#else
|
|
|
|
FSRef ref;
|
|
|
|
CFStringRef str;
|
|
|
|
CFURLRef base;
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
if (FSFindFolder(global ? kLocalDomain : kUserDomain,
|
|
|
|
kApplicationSupportFolderType,
|
|
|
|
kDontCreateFolder, &ref) < 0) return NULL;
|
|
|
|
base = CFURLCreateFromFSRef(NULL, &ref);
|
|
|
|
if (!base) return NULL;
|
|
|
|
str = CFURLCopyFileSystemPath(base, kCFURLPOSIXPathStyle);
|
|
|
|
CFRelease(base);
|
|
|
|
if (!str) return NULL;
|
|
|
|
s = (char*)CFStringGetCStringPtr(str,CFStringGetSystemEncoding());
|
|
|
|
if (s) s = strdup(s);
|
|
|
|
CFRelease(str);
|
|
|
|
return s;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2006-04-23 06:44:19 +00:00
|
|
|
int Bcorrectfilename(char *filename, int removefn)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
char *fn;
|
2008-06-11 02:33:23 +00:00
|
|
|
char *tokarr[64], *first, *next = NULL, *token;
|
2006-04-24 19:04:22 +00:00
|
|
|
int i, ntok = 0, leadslash = 0, trailslash = 0;
|
|
|
|
|
|
|
|
fn = strdup(filename);
|
|
|
|
if (!fn) return -1;
|
|
|
|
|
2007-12-12 17:42:14 +00:00
|
|
|
for (first=fn; *first; first++)
|
|
|
|
{
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _WIN32
|
2006-04-24 19:04:22 +00:00
|
|
|
if (*first == '\\') *first = '/';
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
}
|
|
|
|
leadslash = (*fn == '/');
|
|
|
|
trailslash = (first>fn && first[-1] == '/');
|
|
|
|
|
|
|
|
first = fn;
|
2007-12-12 17:42:14 +00:00
|
|
|
do
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
token = Bstrtoken(first, "/", &next, 1);
|
|
|
|
first = NULL;
|
|
|
|
if (!token) break;
|
|
|
|
else if (token[0] == 0) continue;
|
|
|
|
else if (token[0] == '.' && token[1] == 0) continue;
|
|
|
|
else if (token[0] == '.' && token[1] == '.' && token[2] == 0) ntok = max(0,ntok-1);
|
|
|
|
else tokarr[ntok++] = token;
|
2007-12-12 17:42:14 +00:00
|
|
|
}
|
|
|
|
while (1);
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2007-12-12 17:42:14 +00:00
|
|
|
if (!trailslash && removefn) { ntok = max(0,ntok-1); trailslash = 1; }
|
2006-04-24 19:04:22 +00:00
|
|
|
if (ntok == 0 && trailslash && leadslash) trailslash = 0;
|
|
|
|
|
|
|
|
first = filename;
|
|
|
|
if (leadslash) *(first++) = '/';
|
2007-12-12 17:42:14 +00:00
|
|
|
for (i=0; i<ntok; i++)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
if (i>0) *(first++) = '/';
|
|
|
|
for (token=tokarr[i]; *token; token++)
|
|
|
|
*(first++) = *token;
|
|
|
|
}
|
|
|
|
if (trailslash) *(first++) = '/';
|
|
|
|
*(first++) = 0;
|
2006-04-23 06:44:19 +00:00
|
|
|
|
2006-04-24 18:52:29 +00:00
|
|
|
Bfree(fn);
|
2006-04-24 19:04:22 +00:00
|
|
|
return 0;
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bcanonicalisefilename(char *filename, int removefn)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
char cwd[BMAX_PATH], fn[BMAX_PATH], *p;
|
|
|
|
char *fnp = filename;
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _WIN32
|
2006-04-24 19:04:22 +00:00
|
|
|
int drv = 0;
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _WIN32
|
2006-04-24 19:04:22 +00:00
|
|
|
{
|
2007-12-12 17:42:14 +00:00
|
|
|
if (filename[0] && filename[1] == ':')
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
// filename is prefixed with a drive
|
|
|
|
drv = toupper(filename[0])-'A' + 1;
|
|
|
|
fnp += 2;
|
|
|
|
}
|
|
|
|
if (!_getdcwd(drv, cwd, sizeof(cwd))) return -1;
|
|
|
|
for (p=cwd; *p; p++) if (*p == '\\') *p = '/';
|
|
|
|
}
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
if (!getcwd(cwd,sizeof(cwd))) return -1;
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
p = strrchr(cwd,'/'); if (!p || p[1]) strcat(cwd, "/");
|
|
|
|
|
|
|
|
strcpy(fn, fnp);
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _WIN32
|
2006-04-24 19:04:22 +00:00
|
|
|
for (p=fn; *p; p++) if (*p == '\\') *p = '/';
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
|
2007-12-12 17:42:14 +00:00
|
|
|
if (fn[0] != '/')
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
// we are dealing with a path relative to the current directory
|
|
|
|
strcpy(filename, cwd);
|
|
|
|
strcat(filename, fn);
|
2007-12-12 17:42:14 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _WIN32
|
2006-04-24 19:04:22 +00:00
|
|
|
filename[0] = cwd[0];
|
|
|
|
filename[1] = ':';
|
|
|
|
filename[2] = 0;
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
filename[0] = 0;
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
strcat(filename, fn);
|
|
|
|
}
|
|
|
|
fnp = filename;
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _WIN32
|
2006-04-24 19:04:22 +00:00
|
|
|
fnp += 2; // skip the drive
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2008-03-22 10:23:57 +00:00
|
|
|
UNREFERENCED_PARAMETER(removefn); // change the call below to use removefn instead of 1?
|
2006-04-24 19:04:22 +00:00
|
|
|
return Bcorrectfilename(fnp,1);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *Bgetsystemdrives(void)
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
2006-04-24 19:04:22 +00:00
|
|
|
char *str, *p;
|
|
|
|
DWORD drv, mask;
|
|
|
|
int number=0;
|
|
|
|
|
|
|
|
drv = GetLogicalDrives();
|
|
|
|
if (drv == 0) return NULL;
|
|
|
|
|
2007-12-12 17:42:14 +00:00
|
|
|
for (mask=1; mask<0x8000000l; mask<<=1)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
if ((drv&mask) == 0) continue;
|
|
|
|
number++;
|
|
|
|
}
|
|
|
|
|
|
|
|
str = p = (char *)malloc(1 + (3*number));
|
|
|
|
if (!str) return NULL;
|
|
|
|
|
|
|
|
number = 0;
|
2007-12-12 17:42:14 +00:00
|
|
|
for (mask=1; mask<0x8000000l; mask<<=1, number++)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
if ((drv&mask) == 0) continue;
|
|
|
|
*(p++) = 'A' + number;
|
|
|
|
*(p++) = ':';
|
|
|
|
*(p++) = 0;
|
|
|
|
}
|
|
|
|
*(p++) = 0;
|
|
|
|
|
|
|
|
return str;
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
// Perhaps have Unix OS's put /, /home/user, and /mnt/* in the "drives" list?
|
|
|
|
return NULL;
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 17:42:14 +00:00
|
|
|
int Bfilelength(int fd)
|
2006-04-23 06:44:19 +00:00
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
struct stat st;
|
|
|
|
if (fstat(fd, &st) < 0) return -1;
|
2007-12-12 17:42:14 +00:00
|
|
|
return(int)(st.st_size);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-12 17:42:14 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _MSC_VER
|
2007-12-12 17:42:14 +00:00
|
|
|
int dir;
|
2006-04-24 19:04:22 +00:00
|
|
|
struct _finddata_t fid;
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
DIR *dir;
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
struct Bdirent info;
|
|
|
|
int status;
|
|
|
|
char name[1];
|
2006-04-23 06:44:19 +00:00
|
|
|
} BDIR_real;
|
|
|
|
|
|
|
|
BDIR* Bopendir(const char *name)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
BDIR_real *dirr;
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _MSC_VER
|
2006-04-24 19:04:22 +00:00
|
|
|
char *t,*tt;
|
|
|
|
t = (char*)malloc(strlen(name)+1+4);
|
|
|
|
if (!t) return NULL;
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
dirr = (BDIR_real*)malloc(sizeof(BDIR_real) + strlen(name));
|
2007-12-12 17:42:14 +00:00
|
|
|
if (!dirr)
|
|
|
|
{
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _MSC_VER
|
2006-04-24 19:04:22 +00:00
|
|
|
free(t);
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2006-04-23 06:44:19 +00:00
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2006-04-24 19:04:22 +00:00
|
|
|
strcpy(t,name);
|
|
|
|
tt = t+strlen(name)-1;
|
|
|
|
while (*tt == ' ' && tt>t) tt--;
|
|
|
|
if (*tt != '/' && *tt != '\\') *(++tt) = '/';
|
|
|
|
*(++tt) = '*';
|
|
|
|
*(++tt) = '.';
|
|
|
|
*(++tt) = '*';
|
|
|
|
*(++tt) = 0;
|
|
|
|
|
|
|
|
dirr->dir = _findfirst(t,&dirr->fid);
|
|
|
|
free(t);
|
2007-12-12 17:42:14 +00:00
|
|
|
if (dirr->dir == -1)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
free(dirr);
|
|
|
|
return NULL;
|
|
|
|
}
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
dirr->dir = opendir(name);
|
2007-12-12 17:42:14 +00:00
|
|
|
if (dirr->dir == NULL)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
free(dirr);
|
|
|
|
return NULL;
|
|
|
|
}
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
dirr->status = 0;
|
|
|
|
strcpy(dirr->name, name);
|
|
|
|
|
|
|
|
return (BDIR*)dirr;
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct Bdirent* Breaddir(BDIR *dir)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
BDIR_real *dirr = (BDIR_real*)dir;
|
|
|
|
struct dirent *de;
|
|
|
|
struct stat st;
|
|
|
|
char *fn;
|
2006-04-23 06:44:19 +00:00
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2007-12-12 17:42:14 +00:00
|
|
|
if (dirr->status > 0)
|
|
|
|
{
|
|
|
|
if (_findnext(dirr->dir,&dirr->fid) != 0)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
dirr->status = -1;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dirr->info.namlen = strlen(dirr->fid.name);
|
|
|
|
dirr->info.name = dirr->fid.name;
|
|
|
|
dirr->status++;
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
de = readdir(dirr->dir);
|
2007-12-12 17:42:14 +00:00
|
|
|
if (de == NULL)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
dirr->status = -1;
|
|
|
|
return NULL;
|
2007-12-12 17:42:14 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
dirr->status++;
|
|
|
|
}
|
|
|
|
//# if defined(__WATCOMC__) || defined(__linux) || defined(__BEOS__) || defined(__QNX__) || defined(SKYOS)
|
|
|
|
dirr->info.namlen = strlen(de->d_name);
|
|
|
|
//# else
|
|
|
|
// dirr->info.namlen = de->d_namlen;
|
|
|
|
//# endif
|
|
|
|
dirr->info.name = de->d_name;
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
dirr->info.mode = 0;
|
|
|
|
dirr->info.size = 0;
|
|
|
|
dirr->info.mtime = 0;
|
2006-04-23 06:44:19 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
fn = (char *)malloc(strlen(dirr->name) + 1 + dirr->info.namlen + 1);
|
2007-12-12 17:42:14 +00:00
|
|
|
if (fn)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
sprintf(fn,"%s/%s",dirr->name,dirr->info.name);
|
2007-12-12 17:42:14 +00:00
|
|
|
if (!stat(fn, &st))
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
dirr->info.mode = st.st_mode;
|
|
|
|
dirr->info.size = st.st_size;
|
|
|
|
dirr->info.mtime = st.st_mtime;
|
|
|
|
}
|
|
|
|
free(fn);
|
|
|
|
}
|
2006-04-23 06:44:19 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
return &dirr->info;
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int Bclosedir(BDIR *dir)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
BDIR_real *dirr = (BDIR_real*)dir;
|
|
|
|
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _MSC_VER
|
2006-04-24 19:04:22 +00:00
|
|
|
_findclose(dirr->dir);
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
closedir(dirr->dir);
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
free(dirr);
|
2006-04-23 06:44:19 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
return 0;
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char *Bstrtoken(char *s, char *delim, char **ptrptr, int chop)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
char *p, *start;
|
|
|
|
|
|
|
|
if (!ptrptr) return NULL;
|
2006-04-23 06:44:19 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
if (s) p = s;
|
|
|
|
else p = *ptrptr;
|
2006-04-23 06:44:19 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
if (!p) return NULL;
|
2006-04-23 06:44:19 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
while (*p != 0 && strchr(delim, *p)) p++;
|
2007-12-12 17:42:14 +00:00
|
|
|
if (*p == 0)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
*ptrptr = NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
start = p;
|
|
|
|
while (*p != 0 && !strchr(delim, *p)) p++;
|
|
|
|
if (*p == 0) *ptrptr = NULL;
|
2007-12-12 17:42:14 +00:00
|
|
|
else
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
if (chop) *(p++) = 0;
|
|
|
|
*ptrptr = p;
|
|
|
|
}
|
2006-04-23 06:44:19 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
return start;
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//Brute-force case-insensitive, slash-insensitive, * and ? wildcard matcher
|
|
|
|
//Given: string i and string j. string j can have wildcards
|
|
|
|
//Returns: 1:matches, 0:doesn't match
|
2007-12-12 17:42:14 +00:00
|
|
|
int Bwildmatch(const char *i, const char *j)
|
2006-04-23 06:44:19 +00:00
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
const char *k;
|
|
|
|
char c0, c1;
|
|
|
|
|
|
|
|
if (!*j) return(1);
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (*j == '*')
|
|
|
|
{
|
2006-11-13 23:12:47 +00:00
|
|
|
for (k=i,j++;*k;k++) if (Bwildmatch(k,j)) return(1);
|
2006-04-24 19:04:22 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!*i) return(0);
|
2007-12-12 17:42:14 +00:00
|
|
|
if (*j == '?') { i++; j++; continue; }
|
2006-04-24 19:04:22 +00:00
|
|
|
c0 = *i; if ((c0 >= 'a') && (c0 <= 'z')) c0 -= 32;
|
|
|
|
c1 = *j; if ((c1 >= 'a') && (c1 <= 'z')) c1 -= 32;
|
2006-04-23 06:44:19 +00:00
|
|
|
#ifdef _WIN32
|
2006-04-24 19:04:22 +00:00
|
|
|
if (c0 == '/') c0 = '\\';
|
|
|
|
if (c1 == '/') c1 = '\\';
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
if (c0 != c1) return(0);
|
|
|
|
i++; j++;
|
2007-12-12 17:42:14 +00:00
|
|
|
}
|
|
|
|
while (*j);
|
2006-04-24 19:04:22 +00:00
|
|
|
return(!*i);
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if !defined(_WIN32)
|
|
|
|
char *Bstrlwr(char *s)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
char *t = s;
|
|
|
|
if (!s) return s;
|
2007-12-12 17:42:14 +00:00
|
|
|
while (*t) { *t = Btolower(*t); t++; }
|
2006-04-24 19:04:22 +00:00
|
|
|
return s;
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *Bstrupr(char *s)
|
|
|
|
{
|
2006-04-24 19:04:22 +00:00
|
|
|
char *t = s;
|
|
|
|
if (!s) return s;
|
2007-12-12 17:42:14 +00:00
|
|
|
while (*t) { *t = Btoupper(*t); t++; }
|
2006-04-24 19:04:22 +00:00
|
|
|
return s;
|
2006-04-23 06:44:19 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// getsysmemsize() -- gets the amount of system memory in the machine
|
|
|
|
//
|
|
|
|
unsigned int Bgetsysmemsize(void)
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
2006-04-24 19:04:22 +00:00
|
|
|
MEMORYSTATUS memst;
|
|
|
|
GlobalMemoryStatus(&memst);
|
|
|
|
return (unsigned int)memst.dwTotalPhys;
|
2006-04-23 06:44:19 +00:00
|
|
|
#elif (defined(_SC_PAGE_SIZE) || defined(_SC_PAGESIZE)) && defined(_SC_PHYS_PAGES)
|
2006-04-24 19:04:22 +00:00
|
|
|
unsigned int siz = 0x7fffffff;
|
2007-12-12 17:42:14 +00:00
|
|
|
int scpagesiz, scphyspages;
|
2006-04-23 06:44:19 +00:00
|
|
|
|
|
|
|
#ifdef _SC_PAGE_SIZE
|
2006-04-24 19:04:22 +00:00
|
|
|
scpagesiz = sysconf(_SC_PAGE_SIZE);
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
scpagesiz = sysconf(_SC_PAGESIZE);
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
2006-04-24 19:04:22 +00:00
|
|
|
scphyspages = sysconf(_SC_PHYS_PAGES);
|
|
|
|
if (scpagesiz >= 0 && scphyspages >= 0)
|
|
|
|
siz = (unsigned int)min(longlong(0x7fffffff), (int64)scpagesiz * (int64)scphyspages);
|
2006-04-23 06:44:19 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
//initprintf("Bgetsysmemsize(): %d pages of %d bytes, %d bytes of system memory\n",
|
|
|
|
// scphyspages, scpagesiz, siz);
|
2006-04-23 06:44:19 +00:00
|
|
|
|
2006-04-24 19:04:22 +00:00
|
|
|
return siz;
|
2006-04-23 06:44:19 +00:00
|
|
|
#else
|
2006-04-24 19:04:22 +00:00
|
|
|
return 0x7fffffff;
|
2006-04-23 06:44:19 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|