Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
444
Src/external_dependencies/openmpt-trunk/include/unrar/strfn.cpp
vendored
Normal file
444
Src/external_dependencies/openmpt-trunk/include/unrar/strfn.cpp
vendored
Normal file
|
@ -0,0 +1,444 @@
|
|||
#include "rar.hpp"
|
||||
|
||||
const char *NullToEmpty(const char *Str)
|
||||
{
|
||||
return Str==NULL ? "":Str;
|
||||
}
|
||||
|
||||
|
||||
const wchar *NullToEmpty(const wchar *Str)
|
||||
{
|
||||
return Str==NULL ? L"":Str;
|
||||
}
|
||||
|
||||
|
||||
void IntToExt(const char *Src,char *Dest,size_t DestSize)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
// OemToCharBuff does not stop at 0, so let's check source length.
|
||||
size_t SrcLength=strlen(Src)+1;
|
||||
if (DestSize>SrcLength)
|
||||
DestSize=SrcLength;
|
||||
OemToCharBuffA(Src,Dest,(DWORD)DestSize);
|
||||
Dest[DestSize-1]=0;
|
||||
#else
|
||||
if (Dest!=Src)
|
||||
strncpyz(Dest,Src,DestSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Convert archived names and comments to Unicode.
|
||||
// Allows user to select a code page in GUI.
|
||||
void ArcCharToWide(const char *Src,wchar *Dest,size_t DestSize,ACTW_ENCODING Encoding)
|
||||
{
|
||||
#if defined(_WIN_ALL) // Console Windows RAR.
|
||||
if (Encoding==ACTW_UTF8)
|
||||
UtfToWide(Src,Dest,DestSize);
|
||||
else
|
||||
{
|
||||
Array<char> NameA;
|
||||
if (Encoding==ACTW_OEM)
|
||||
{
|
||||
NameA.Alloc(DestSize+1);
|
||||
IntToExt(Src,&NameA[0],NameA.Size());
|
||||
Src=&NameA[0];
|
||||
}
|
||||
CharToWide(Src,Dest,DestSize);
|
||||
}
|
||||
#else // RAR for Unix.
|
||||
if (Encoding==ACTW_UTF8)
|
||||
UtfToWide(Src,Dest,DestSize);
|
||||
else
|
||||
CharToWide(Src,Dest,DestSize);
|
||||
#endif
|
||||
// Ensure that we return a zero terminate string for security reason.
|
||||
// While [Jni]CharToWide might already do it, be protected in case of future
|
||||
// changes in these functions.
|
||||
if (DestSize>0)
|
||||
Dest[DestSize-1]=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int stricomp(const char *s1,const char *s2)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
return CompareStringA(LOCALE_USER_DEFAULT,NORM_IGNORECASE|SORT_STRINGSORT,s1,-1,s2,-1)-2;
|
||||
#else
|
||||
while (toupper(*s1)==toupper(*s2))
|
||||
{
|
||||
if (*s1==0)
|
||||
return 0;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return s1 < s2 ? -1 : 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int strnicomp(const char *s1,const char *s2,size_t n)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
// If we specify 'n' exceeding the actual string length, CompareString goes
|
||||
// beyond the trailing zero and compares garbage. So we need to limit 'n'
|
||||
// to real string length.
|
||||
// It is important to use strnlen (or memchr(...,0)) instead of strlen,
|
||||
// because data can be not zero terminated.
|
||||
size_t l1=Min(strnlen(s1,n),n);
|
||||
size_t l2=Min(strnlen(s2,n),n);
|
||||
return CompareStringA(LOCALE_USER_DEFAULT,NORM_IGNORECASE|SORT_STRINGSORT,s1,(int)l1,s2,(int)l2)-2;
|
||||
#else
|
||||
if (n==0)
|
||||
return 0;
|
||||
while (toupper(*s1)==toupper(*s2))
|
||||
{
|
||||
if (*s1==0 || --n==0)
|
||||
return 0;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return s1 < s2 ? -1 : 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
wchar* RemoveEOL(wchar *Str)
|
||||
{
|
||||
for (int I=(int)wcslen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n' || Str[I]==' ' || Str[I]=='\t');I--)
|
||||
Str[I]=0;
|
||||
return Str;
|
||||
}
|
||||
|
||||
|
||||
wchar* RemoveLF(wchar *Str)
|
||||
{
|
||||
for (int I=(int)wcslen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n');I--)
|
||||
Str[I]=0;
|
||||
return Str;
|
||||
}
|
||||
|
||||
|
||||
#if defined(SFX_MODULE)
|
||||
// char version of etoupperw. Used in console SFX module only.
|
||||
// Fast toupper for English only input and output. Additionally to speed,
|
||||
// it also avoids Turkish small i to big I with dot conversion problem.
|
||||
// We do not define 'c' as 'int' to avoid necessity to cast all
|
||||
// signed chars passed to this function to unsigned char.
|
||||
unsigned char etoupper(unsigned char c)
|
||||
{
|
||||
return c>='a' && c<='z' ? c-'a'+'A' : c;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Fast toupper for English only input and output. Additionally to speed,
|
||||
// it also avoids Turkish small i to big I with dot conversion problem.
|
||||
// We do not define 'c' as 'int' to avoid necessity to cast all
|
||||
// signed wchars passed to this function to unsigned char.
|
||||
wchar etoupperw(wchar c)
|
||||
{
|
||||
return c>='a' && c<='z' ? c-'a'+'A' : c;
|
||||
}
|
||||
|
||||
|
||||
// We do not want to cast every signed char to unsigned when passing to
|
||||
// isdigit, so we implement the replacement. Shall work for Unicode too.
|
||||
// If chars are signed, conversion from char to int could generate negative
|
||||
// values, resulting in undefined behavior in standard isdigit.
|
||||
bool IsDigit(int ch)
|
||||
{
|
||||
return ch>='0' && ch<='9';
|
||||
}
|
||||
|
||||
|
||||
// We do not want to cast every signed char to unsigned when passing to
|
||||
// isspace, so we implement the replacement. Shall work for Unicode too.
|
||||
// If chars are signed, conversion from char to int could generate negative
|
||||
// values, resulting in undefined behavior in standard isspace.
|
||||
bool IsSpace(int ch)
|
||||
{
|
||||
return ch==' ' || ch=='\t';
|
||||
}
|
||||
|
||||
|
||||
// We do not want to cast every signed char to unsigned when passing to
|
||||
// isalpha, so we implement the replacement. Shall work for Unicode too.
|
||||
// If chars are signed, conversion from char to int could generate negative
|
||||
// values, resulting in undefined behavior in standard function.
|
||||
bool IsAlpha(int ch)
|
||||
{
|
||||
return ch>='A' && ch<='Z' || ch>='a' && ch<='z';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void BinToHex(const byte *Bin,size_t BinSize,char *HexA,wchar *HexW,size_t HexSize)
|
||||
{
|
||||
uint A=0,W=0; // ASCII and Unicode hex output positions.
|
||||
for (uint I=0;I<BinSize;I++)
|
||||
{
|
||||
uint High=Bin[I] >> 4;
|
||||
uint Low=Bin[I] & 0xf;
|
||||
uint HighHex=High>9 ? 'a'+High-10:'0'+High;
|
||||
uint LowHex=Low>9 ? 'a'+Low-10:'0'+Low;
|
||||
if (HexA!=NULL && A<HexSize-2) // Need space for 2 chars and final zero.
|
||||
{
|
||||
HexA[A++]=(char)HighHex;
|
||||
HexA[A++]=(char)LowHex;
|
||||
}
|
||||
if (HexW!=NULL && W<HexSize-2) // Need space for 2 chars and final zero.
|
||||
{
|
||||
HexW[W++]=HighHex;
|
||||
HexW[W++]=LowHex;
|
||||
}
|
||||
}
|
||||
if (HexA!=NULL && HexSize>0)
|
||||
HexA[A]=0;
|
||||
if (HexW!=NULL && HexSize>0)
|
||||
HexW[W]=0;
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
uint GetDigits(uint Number)
|
||||
{
|
||||
uint Digits=1;
|
||||
while (Number>=10)
|
||||
{
|
||||
Number/=10;
|
||||
Digits++;
|
||||
}
|
||||
return Digits;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool LowAscii(const char *Str)
|
||||
{
|
||||
for (size_t I=0;Str[I]!=0;I++)
|
||||
if (/*(byte)Str[I]<32 || */(byte)Str[I]>127)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool LowAscii(const wchar *Str)
|
||||
{
|
||||
for (size_t I=0;Str[I]!=0;I++)
|
||||
{
|
||||
// We convert wchar_t to uint just in case if some compiler
|
||||
// uses signed wchar_t.
|
||||
if (/*(uint)Str[I]<32 || */(uint)Str[I]>127)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int wcsicompc(const wchar *s1,const wchar *s2) // For path comparison.
|
||||
{
|
||||
#if defined(_UNIX)
|
||||
return wcscmp(s1,s2);
|
||||
#else
|
||||
return wcsicomp(s1,s2);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int wcsnicompc(const wchar *s1,const wchar *s2,size_t n)
|
||||
{
|
||||
#if defined(_UNIX)
|
||||
return wcsncmp(s1,s2,n);
|
||||
#else
|
||||
return wcsnicomp(s1,s2,n);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Safe copy: copies maxlen-1 max and for maxlen>0 returns zero terminated dest.
|
||||
void strncpyz(char *dest, const char *src, size_t maxlen)
|
||||
{
|
||||
if (maxlen>0)
|
||||
{
|
||||
while (--maxlen>0 && *src!=0)
|
||||
*dest++=*src++;
|
||||
*dest=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Safe copy: copies maxlen-1 max and for maxlen>0 returns zero terminated dest.
|
||||
void wcsncpyz(wchar *dest, const wchar *src, size_t maxlen)
|
||||
{
|
||||
if (maxlen>0)
|
||||
{
|
||||
while (--maxlen>0 && *src!=0)
|
||||
*dest++=*src++;
|
||||
*dest=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Safe append: resulting dest length cannot exceed maxlen and dest
|
||||
// is always zero terminated. 'maxlen' parameter defines the entire
|
||||
// dest buffer size and is not compatible with wcsncat.
|
||||
void strncatz(char* dest, const char* src, size_t maxlen)
|
||||
{
|
||||
size_t length = strlen(dest);
|
||||
if (maxlen > length)
|
||||
strncpyz(dest + length, src, maxlen - length);
|
||||
}
|
||||
|
||||
|
||||
// Safe append: resulting dest length cannot exceed maxlen and dest
|
||||
// is always zero terminated. 'maxlen' parameter defines the entire
|
||||
// dest buffer size and is not compatible with wcsncat.
|
||||
void wcsncatz(wchar* dest, const wchar* src, size_t maxlen)
|
||||
{
|
||||
size_t length = wcslen(dest);
|
||||
if (maxlen > length)
|
||||
wcsncpyz(dest + length, src, maxlen - length);
|
||||
}
|
||||
|
||||
|
||||
void itoa(int64 n,char *Str,size_t MaxSize)
|
||||
{
|
||||
char NumStr[50];
|
||||
size_t Pos=0;
|
||||
|
||||
int Neg=n < 0 ? 1 : 0;
|
||||
if (Neg)
|
||||
n=-n;
|
||||
|
||||
do
|
||||
{
|
||||
if (Pos+1>=MaxSize-Neg)
|
||||
break;
|
||||
NumStr[Pos++]=char(n%10)+'0';
|
||||
n=n/10;
|
||||
} while (n!=0);
|
||||
|
||||
if (Neg)
|
||||
NumStr[Pos++]='-';
|
||||
|
||||
for (size_t I=0;I<Pos;I++)
|
||||
Str[I]=NumStr[Pos-I-1];
|
||||
Str[Pos]=0;
|
||||
}
|
||||
|
||||
|
||||
void itoa(int64 n,wchar *Str,size_t MaxSize)
|
||||
{
|
||||
wchar NumStr[50];
|
||||
size_t Pos=0;
|
||||
|
||||
int Neg=n < 0 ? 1 : 0;
|
||||
if (Neg)
|
||||
n=-n;
|
||||
|
||||
do
|
||||
{
|
||||
if (Pos+1>=MaxSize-Neg)
|
||||
break;
|
||||
NumStr[Pos++]=wchar(n%10)+'0';
|
||||
n=n/10;
|
||||
} while (n!=0);
|
||||
|
||||
if (Neg)
|
||||
NumStr[Pos++]='-';
|
||||
|
||||
for (size_t I=0;I<Pos;I++)
|
||||
Str[I]=NumStr[Pos-I-1];
|
||||
Str[Pos]=0;
|
||||
}
|
||||
|
||||
|
||||
const wchar* GetWide(const char *Src)
|
||||
{
|
||||
const size_t MaxLength=NM;
|
||||
static wchar StrTable[4][MaxLength];
|
||||
static uint StrNum=0;
|
||||
if (++StrNum >= ASIZE(StrTable))
|
||||
StrNum=0;
|
||||
wchar *Str=StrTable[StrNum];
|
||||
CharToWide(Src,Str,MaxLength);
|
||||
Str[MaxLength-1]=0;
|
||||
return Str;
|
||||
}
|
||||
|
||||
|
||||
// Parse string containing parameters separated with spaces.
|
||||
// Support quote marks. Param can be NULL to return the pointer to next
|
||||
// parameter, which can be used to estimate the buffer size for Param.
|
||||
const wchar* GetCmdParam(const wchar *CmdLine,wchar *Param,size_t MaxSize)
|
||||
{
|
||||
while (IsSpace(*CmdLine))
|
||||
CmdLine++;
|
||||
if (*CmdLine==0)
|
||||
return NULL;
|
||||
|
||||
size_t ParamSize=0;
|
||||
bool Quote=false;
|
||||
while (*CmdLine!=0 && (Quote || !IsSpace(*CmdLine)))
|
||||
{
|
||||
if (*CmdLine=='\"')
|
||||
{
|
||||
if (CmdLine[1]=='\"')
|
||||
{
|
||||
// Insert the quote character instead of two adjoining quote characters.
|
||||
if (Param!=NULL && ParamSize<MaxSize-1)
|
||||
Param[ParamSize++]='\"';
|
||||
CmdLine++;
|
||||
}
|
||||
else
|
||||
Quote=!Quote;
|
||||
}
|
||||
else
|
||||
if (Param!=NULL && ParamSize<MaxSize-1)
|
||||
Param[ParamSize++]=*CmdLine;
|
||||
CmdLine++;
|
||||
}
|
||||
if (Param!=NULL)
|
||||
Param[ParamSize]=0;
|
||||
return CmdLine;
|
||||
}
|
||||
|
||||
|
||||
#ifndef RARDLL
|
||||
// For compatibility with existing translations we use %s to print Unicode
|
||||
// strings in format strings and convert them to %ls here. %s could work
|
||||
// without such conversion in Windows, but not in Unix wprintf.
|
||||
void PrintfPrepareFmt(const wchar *Org,wchar *Cvt,size_t MaxSize)
|
||||
{
|
||||
uint Src=0,Dest=0;
|
||||
while (Org[Src]!=0 && Dest<MaxSize-1)
|
||||
{
|
||||
if (Org[Src]=='%' && (Src==0 || Org[Src-1]!='%'))
|
||||
{
|
||||
uint SPos=Src+1;
|
||||
// Skipping a possible width specifier like %-50s.
|
||||
while (IsDigit(Org[SPos]) || Org[SPos]=='-')
|
||||
SPos++;
|
||||
if (Org[SPos]=='s' && Dest<MaxSize-(SPos-Src+1))
|
||||
{
|
||||
while (Src<SPos)
|
||||
Cvt[Dest++]=Org[Src++];
|
||||
Cvt[Dest++]='l';
|
||||
}
|
||||
}
|
||||
#ifdef _WIN_ALL
|
||||
// Convert \n to \r\n in Windows. Important when writing to log,
|
||||
// so other tools like Notebook can view resulting log properly.
|
||||
if (Org[Src]=='\n' && (Src==0 || Org[Src-1]!='\r'))
|
||||
Cvt[Dest++]='\r';
|
||||
#endif
|
||||
|
||||
Cvt[Dest++]=Org[Src++];
|
||||
}
|
||||
Cvt[Dest]=0;
|
||||
}
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue