comment, cleanup, and whatnot
This commit is contained in:
+73
-93
@@ -166,21 +166,21 @@ RString BinaryToHex( const RString &sString )
|
|||||||
|
|
||||||
bool HexToBinary( const RString &s, unsigned char *stringOut )
|
bool HexToBinary( const RString &s, unsigned char *stringOut )
|
||||||
{
|
{
|
||||||
if( !IsHexVal(s) )
|
if( !IsHexVal(s) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for( int i=0; true; i++ )
|
for( int i=0; true; i++ )
|
||||||
{
|
{
|
||||||
if( (int)s.size() <= i*2 )
|
if( (int)s.size() <= i*2 )
|
||||||
break;
|
break;
|
||||||
RString sByte = s.substr( i*2, 2 );
|
RString sByte = s.substr( i*2, 2 );
|
||||||
|
|
||||||
uint8_t val = 0;
|
uint8_t val = 0;
|
||||||
if( sscanf( sByte, "%hhx", &val ) != 1 )
|
if( sscanf( sByte, "%hhx", &val ) != 1 )
|
||||||
return false;
|
return false;
|
||||||
stringOut[i] = val;
|
stringOut[i] = val;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HexToBinary( const RString &s, RString &sOut )
|
bool HexToBinary( const RString &s, RString &sOut )
|
||||||
@@ -311,7 +311,6 @@ struct tm GetLocalTime()
|
|||||||
return tm;
|
return tm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RString ssprintf( const char *fmt, ...)
|
RString ssprintf( const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list va;
|
va_list va;
|
||||||
@@ -393,8 +392,8 @@ RString vssprintf( const char *szFormat, va_list argList )
|
|||||||
return sStr;
|
return sStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Windows uses %I64i to format a 64-bit int, instead of %lli. Convert "a b %lli %-3llu c d"
|
/* Windows uses %I64i to format a 64-bit int, instead of %lli. Convert "a b %lli %-3llu c d"
|
||||||
* to "a b %I64 %-3I64u c d". This assumes a well-formed format string; invalid format strings
|
* to "a b %I64 %-3I64u c d". This assumes a well-formed format string; invalid format strings
|
||||||
* should not crash, but the results are undefined. */
|
* should not crash, but the results are undefined. */
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
RString ConvertI64FormatString( const RString &sStr )
|
RString ConvertI64FormatString( const RString &sStr )
|
||||||
@@ -681,7 +680,6 @@ RString DwiEscape( const char *cUnescaped, int len )
|
|||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class S>
|
template <class S>
|
||||||
static int DelimitorLength( const S &Delimitor )
|
static int DelimitorLength( const S &Delimitor )
|
||||||
{
|
{
|
||||||
@@ -731,7 +729,6 @@ void do_split( const S &Source, const C Delimitor, vector<S> &AddIt, const bool
|
|||||||
} while ( startpos <= Source.size() );
|
} while ( startpos <= Source.size() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void split( const RString &sSource, const RString &sDelimitor, vector<RString> &asAddIt, const bool bIgnoreEmpty )
|
void split( const RString &sSource, const RString &sDelimitor, vector<RString> &asAddIt, const bool bIgnoreEmpty )
|
||||||
{
|
{
|
||||||
if( sDelimitor.size() == 1 )
|
if( sDelimitor.size() == 1 )
|
||||||
@@ -760,14 +757,14 @@ while( 1 )
|
|||||||
str[start] = 'Q';
|
str[start] = 'Q';
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <class S>
|
template <class S>
|
||||||
void do_split( const S &Source, const S &Delimitor, int &begin, int &size, int len, const bool bIgnoreEmpty )
|
void do_split( const S &Source, const S &Delimitor, int &begin, int &size, int len, const bool bIgnoreEmpty )
|
||||||
{
|
{
|
||||||
if( size != -1 )
|
if( size != -1 )
|
||||||
{
|
{
|
||||||
/* Start points to the beginning of the last delimiter. Move it up. */
|
// Start points to the beginning of the last delimiter. Move it up.
|
||||||
begin += size+Delimitor.size();
|
begin += size+Delimitor.size();
|
||||||
begin = min( begin, len );
|
begin = min( begin, len );
|
||||||
}
|
}
|
||||||
@@ -776,14 +773,14 @@ void do_split( const S &Source, const S &Delimitor, int &begin, int &size, int l
|
|||||||
|
|
||||||
if( bIgnoreEmpty )
|
if( bIgnoreEmpty )
|
||||||
{
|
{
|
||||||
/* Skip delims. */
|
// Skip delims.
|
||||||
while( begin + Delimitor.size() < Source.size() &&
|
while( begin + Delimitor.size() < Source.size() &&
|
||||||
!Source.compare( begin, Delimitor.size(), Delimitor ) )
|
!Source.compare( begin, Delimitor.size(), Delimitor ) )
|
||||||
++begin;
|
++begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Where's the string function to find within a substring? C++ strings apparently
|
/* Where's the string function to find within a substring?
|
||||||
* are missing that ... */
|
* C++ strings apparently are missing that ... */
|
||||||
size_t pos;
|
size_t pos;
|
||||||
if( Delimitor.size() == 1 )
|
if( Delimitor.size() == 1 )
|
||||||
pos = Source.find( Delimitor[0], begin );
|
pos = Source.find( Delimitor[0], begin );
|
||||||
@@ -797,7 +794,6 @@ void do_split( const S &Source, const S &Delimitor, int &begin, int &size, int l
|
|||||||
void split( const RString &Source, const RString &Delimitor, int &begin, int &size, int len, const bool bIgnoreEmpty )
|
void split( const RString &Source, const RString &Delimitor, int &begin, int &size, int len, const bool bIgnoreEmpty )
|
||||||
{
|
{
|
||||||
do_split( Source, Delimitor, begin, size, len, bIgnoreEmpty );
|
do_split( Source, Delimitor, begin, size, len, bIgnoreEmpty );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void split( const wstring &Source, const wstring &Delimitor, int &begin, int &size, int len, const bool bIgnoreEmpty )
|
void split( const wstring &Source, const wstring &Delimitor, int &begin, int &size, int len, const bool bIgnoreEmpty )
|
||||||
@@ -815,8 +811,6 @@ void split( const wstring &Source, const wstring &Delimitor, int &begin, int &si
|
|||||||
do_split( Source, Delimitor, begin, size, Source.size(), bIgnoreEmpty );
|
do_split( Source, Delimitor, begin, size, Source.size(), bIgnoreEmpty );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* foo\fum\ -> "foo\fum\", "", ""
|
* foo\fum\ -> "foo\fum\", "", ""
|
||||||
* c:\foo\bar.txt -> "c:\foo\", "bar", ".txt"
|
* c:\foo\bar.txt -> "c:\foo\", "bar", ".txt"
|
||||||
@@ -853,7 +847,6 @@ void splitpath( const RString &sPath, RString &sDir, RString &sFilename, RString
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* "foo.bar", "baz" -> "foo.baz"
|
/* "foo.bar", "baz" -> "foo.baz"
|
||||||
* "foo", "baz" -> "foo.baz"
|
* "foo", "baz" -> "foo.baz"
|
||||||
* "foo.bar", "" -> "foo" */
|
* "foo.bar", "" -> "foo" */
|
||||||
@@ -902,12 +895,10 @@ void MakeValidFilename( RString &sName )
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* We could replace with closest matches in ASCII: convert the character
|
||||||
* We could replace with closest matches in ASCII: convert the character to UTF-8
|
* to UTF-8 NFD (decomposed) (maybe NFKD?), and see if the first
|
||||||
* NFD (decomposed) (maybe NFKD?), and see if the first character is ASCII.
|
* character is ASCII. This is useless for non-Western languages,
|
||||||
*
|
* since we'll replace the whole filename. */
|
||||||
* This is useless for non-Western languages, since we'll replace the whole filename.
|
|
||||||
*/
|
|
||||||
wsName[i] = '_';
|
wsName[i] = '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -929,13 +920,11 @@ void GetCommandLineArguments( int &argc, char **&argv )
|
|||||||
argv = g_argv;
|
argv = g_argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Search for the commandline argument given; eg. "test" searches for the
|
||||||
* Search for the commandline argument given; eg. "test" searches for the
|
|
||||||
* option "--test". All commandline arguments are getopt_long style: --foo;
|
* option "--test". All commandline arguments are getopt_long style: --foo;
|
||||||
* short arguments (-x) are not supported. (These are not intended for
|
* short arguments (-x) are not supported. (These are not intended for
|
||||||
* common, general use, so having short options isn't currently needed.)
|
* common, general use, so having short options isn't currently needed.)
|
||||||
* If argument is non-NULL, accept an argument.
|
* If argument is non-NULL, accept an argument. */
|
||||||
*/
|
|
||||||
bool GetCommandlineArgument( const RString &option, RString *argument, int iIndex )
|
bool GetCommandlineArgument( const RString &option, RString *argument, int iIndex )
|
||||||
{
|
{
|
||||||
const RString optstr = "--" + option;
|
const RString optstr = "--" + option;
|
||||||
@@ -947,9 +936,9 @@ bool GetCommandlineArgument( const RString &option, RString *argument, int iInde
|
|||||||
const size_t i = CurArgument.find( "=" );
|
const size_t i = CurArgument.find( "=" );
|
||||||
RString CurOption = CurArgument.substr(0,i);
|
RString CurOption = CurArgument.substr(0,i);
|
||||||
if( CurOption.CompareNoCase(optstr) )
|
if( CurOption.CompareNoCase(optstr) )
|
||||||
continue; /* no match */
|
continue; // no match
|
||||||
|
|
||||||
/* Found it. */
|
// Found it.
|
||||||
if( iIndex )
|
if( iIndex )
|
||||||
{
|
{
|
||||||
--iIndex;
|
--iIndex;
|
||||||
@@ -1015,14 +1004,13 @@ void CRC32( unsigned int &iCRC, const void *pVoidBuffer, size_t iSize )
|
|||||||
iCRC ^= 0xFFFFFFFF;
|
iCRC ^= 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int GetHashForString ( const RString &s )
|
unsigned int GetHashForString( const RString &s )
|
||||||
{
|
{
|
||||||
unsigned crc = 0;
|
unsigned crc = 0;
|
||||||
CRC32( crc, s.data(), s.size() );
|
CRC32( crc, s.data(), s.size() );
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return true if "dir" is empty or does not exist. */
|
/* Return true if "dir" is empty or does not exist. */
|
||||||
bool DirectoryIsEmpty( const RString &sDir )
|
bool DirectoryIsEmpty( const RString &sDir )
|
||||||
{
|
{
|
||||||
@@ -1131,7 +1119,7 @@ void TrimRight( RString &sStr, const char *s )
|
|||||||
while( n > 0 && strchr(s, sStr[n-1]) )
|
while( n > 0 && strchr(s, sStr[n-1]) )
|
||||||
n--;
|
n--;
|
||||||
|
|
||||||
/* Delete from n to the end. If n == sStr.size(), nothing is deleted;
|
/* Delete from n to the end. If n == sStr.size(), nothing is deleted;
|
||||||
* if n == 0, the whole string is erased. */
|
* if n == 0, the whole string is erased. */
|
||||||
sStr.erase( sStr.begin()+n, sStr.end() );
|
sStr.erase( sStr.begin()+n, sStr.end() );
|
||||||
}
|
}
|
||||||
@@ -1200,7 +1188,7 @@ void StripMacResourceForks( vector<RString> &vs )
|
|||||||
RemoveIf( vs, MacResourceFork );
|
RemoveIf( vs, MacResourceFork );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* path is a .redir pathname. Read it and return the real one. */
|
// path is a .redir pathname. Read it and return the real one.
|
||||||
RString DerefRedir( const RString &_path )
|
RString DerefRedir( const RString &_path )
|
||||||
{
|
{
|
||||||
RString sPath = _path;
|
RString sPath = _path;
|
||||||
@@ -1211,9 +1199,10 @@ RString DerefRedir( const RString &_path )
|
|||||||
return sPath;
|
return sPath;
|
||||||
|
|
||||||
RString sNewFileName;
|
RString sNewFileName;
|
||||||
|
// todo: figure out how to make this UTF-8 safe. -aj
|
||||||
GetFileContents( sPath, sNewFileName, true );
|
GetFileContents( sPath, sNewFileName, true );
|
||||||
|
|
||||||
/* Empty is invalid. */
|
// Empty is invalid.
|
||||||
if( sNewFileName == "" )
|
if( sNewFileName == "" )
|
||||||
return RString();
|
return RString();
|
||||||
|
|
||||||
@@ -1239,7 +1228,7 @@ RString DerefRedir( const RString &_path )
|
|||||||
|
|
||||||
bool GetFileContents( const RString &sPath, RString &sOut, bool bOneLine )
|
bool GetFileContents( const RString &sPath, RString &sOut, bool bOneLine )
|
||||||
{
|
{
|
||||||
/* Don't warn if the file doesn't exist, but do warn if it exists and fails to open. */
|
// Don't warn if the file doesn't exist, but do warn if it exists and fails to open.
|
||||||
if( !IsAFile(sPath) )
|
if( !IsAFile(sPath) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -1395,9 +1384,6 @@ bool Regex::Replace( const RString &sReplacement, const RString &sSubject, RStri
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Given a UTF-8 byte, return the length of the codepoint (if a start code)
|
/* Given a UTF-8 byte, return the length of the codepoint (if a start code)
|
||||||
* or 0 if it's a continuation byte. */
|
* or 0 if it's a continuation byte. */
|
||||||
int utf8_get_char_len( char p )
|
int utf8_get_char_len( char p )
|
||||||
@@ -1417,15 +1403,15 @@ static inline bool is_utf8_continuation_byte( char c )
|
|||||||
return (c & 0xC0) == 0x80;
|
return (c & 0xC0) == 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decode one codepoint at start; advance start and place the result in ch. If
|
/* Decode one codepoint at start; advance start and place the result in ch.
|
||||||
* the encoded string is invalid, false is returned. */
|
* If the encoded string is invalid, false is returned. */
|
||||||
bool utf8_to_wchar_ec( const RString &s, unsigned &start, wchar_t &ch )
|
bool utf8_to_wchar_ec( const RString &s, unsigned &start, wchar_t &ch )
|
||||||
{
|
{
|
||||||
if( start >= s.size() )
|
if( start >= s.size() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( is_utf8_continuation_byte( s[start] ) || /* misplaced continuation byte */
|
if( is_utf8_continuation_byte( s[start] ) || /* misplaced continuation byte */
|
||||||
(s[start] & 0xFE) == 0xFE ) /* 0xFE, 0xFF */
|
(s[start] & 0xFE) == 0xFE ) /* 0xFE, 0xFF */
|
||||||
{
|
{
|
||||||
start += 1;
|
start += 1;
|
||||||
return false;
|
return false;
|
||||||
@@ -1441,7 +1427,7 @@ bool utf8_to_wchar_ec( const RString &s, unsigned &start, wchar_t &ch )
|
|||||||
{
|
{
|
||||||
if( start+i >= s.size() )
|
if( start+i >= s.size() )
|
||||||
{
|
{
|
||||||
/* We expected a continuation byte, but didn't get one. Return error, and point
|
/* We expected a continuation byte, but didn't get one. Return error, and point
|
||||||
* start at the unexpected byte; it's probably a new sequence. */
|
* start at the unexpected byte; it's probably a new sequence. */
|
||||||
start += i;
|
start += i;
|
||||||
return false;
|
return false;
|
||||||
@@ -1450,7 +1436,7 @@ bool utf8_to_wchar_ec( const RString &s, unsigned &start, wchar_t &ch )
|
|||||||
char byte = s[start+i];
|
char byte = s[start+i];
|
||||||
if( !is_utf8_continuation_byte(byte) )
|
if( !is_utf8_continuation_byte(byte) )
|
||||||
{
|
{
|
||||||
/* We expected a continuation byte, but didn't get one. Return error, and point
|
/* We expected a continuation byte, but didn't get one. Return error, and point
|
||||||
* start at the unexpected byte; it's probably a new sequence. */
|
* start at the unexpected byte; it's probably a new sequence. */
|
||||||
start += i;
|
start += i;
|
||||||
return false;
|
return false;
|
||||||
@@ -1490,7 +1476,7 @@ bool utf8_to_wchar( const char *s, size_t iLength, unsigned &start, wchar_t &ch
|
|||||||
|
|
||||||
if( start+len > iLength )
|
if( start+len > iLength )
|
||||||
{
|
{
|
||||||
/* We don't have room for enough continuation bytes. Return error. */
|
// We don't have room for enough continuation bytes. Return error.
|
||||||
start += len;
|
start += len;
|
||||||
ch = L'?';
|
ch = L'?';
|
||||||
return false;
|
return false;
|
||||||
@@ -1540,7 +1526,7 @@ bool utf8_to_wchar( const char *s, size_t iLength, unsigned &start, wchar_t &ch
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* UTF-8 encode ch and append to out. */
|
// UTF-8 encode ch and append to out.
|
||||||
void wchar_to_utf8( wchar_t ch, RString &out )
|
void wchar_to_utf8( wchar_t ch, RString &out )
|
||||||
{
|
{
|
||||||
if( ch < 0x80 ) { out.append( 1, (char) ch ); return; }
|
if( ch < 0x80 ) { out.append( 1, (char) ch ); return; }
|
||||||
@@ -1565,7 +1551,6 @@ void wchar_to_utf8( wchar_t ch, RString &out )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wchar_t utf8_get_char( const RString &s )
|
wchar_t utf8_get_char( const RString &s )
|
||||||
{
|
{
|
||||||
unsigned start = 0;
|
unsigned start = 0;
|
||||||
@@ -1575,9 +1560,7 @@ wchar_t utf8_get_char( const RString &s )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replace invalid sequences in s.
|
||||||
|
|
||||||
/* Replace invalid sequences in s. */
|
|
||||||
void utf8_sanitize( RString &s )
|
void utf8_sanitize( RString &s )
|
||||||
{
|
{
|
||||||
RString ret;
|
RString ret;
|
||||||
@@ -1593,7 +1576,6 @@ void utf8_sanitize( RString &s )
|
|||||||
s = ret;
|
s = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool utf8_is_valid( const RString &s )
|
bool utf8_is_valid( const RString &s )
|
||||||
{
|
{
|
||||||
for( unsigned start = 0; start < s.size(); )
|
for( unsigned start = 0; start < s.size(); )
|
||||||
@@ -1615,6 +1597,7 @@ void utf8_remove_bom( RString &sLine )
|
|||||||
|
|
||||||
static int UnicodeDoUpper( char *p, size_t iLen, const unsigned char pMapping[256] )
|
static int UnicodeDoUpper( char *p, size_t iLen, const unsigned char pMapping[256] )
|
||||||
{
|
{
|
||||||
|
// Note: this has problems with certain accented characters. -aj
|
||||||
wchar_t wc = L'\0';
|
wchar_t wc = L'\0';
|
||||||
unsigned iStart = 0;
|
unsigned iStart = 0;
|
||||||
if( !utf8_to_wchar(p, iLen, iStart, wc) )
|
if( !utf8_to_wchar(p, iLen, iStart, wc) )
|
||||||
@@ -1636,8 +1619,8 @@ static int UnicodeDoUpper( char *p, size_t iLen, const unsigned char pMapping[25
|
|||||||
return iStart;
|
return iStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fast in-place MakeUpper and MakeLower. This only replaces characters with characters of the same UTF-8
|
/* Fast in-place MakeUpper and MakeLower. This only replaces characters with characters of the same UTF-8
|
||||||
* length, so we never have to move the whole string. This is optimized for strings that have no
|
* length, so we never have to move the whole string. This is optimized for strings that have no
|
||||||
* non-ASCII characters. */
|
* non-ASCII characters. */
|
||||||
void MakeUpper( char *p, size_t iLen )
|
void MakeUpper( char *p, size_t iLen )
|
||||||
{
|
{
|
||||||
@@ -1645,7 +1628,7 @@ void MakeUpper( char *p, size_t iLen )
|
|||||||
char *pEnd = p + iLen;
|
char *pEnd = p + iLen;
|
||||||
while( p < pEnd )
|
while( p < pEnd )
|
||||||
{
|
{
|
||||||
/* Fast path: */
|
// Fast path:
|
||||||
if( likely( !(*p & 0x80) ) )
|
if( likely( !(*p & 0x80) ) )
|
||||||
{
|
{
|
||||||
if( unlikely(*p >= 'a' && *p <= 'z') )
|
if( unlikely(*p >= 'a' && *p <= 'z') )
|
||||||
@@ -1665,7 +1648,7 @@ void MakeLower( char *p, size_t iLen )
|
|||||||
char *pEnd = p + iLen;
|
char *pEnd = p + iLen;
|
||||||
while( p < pEnd )
|
while( p < pEnd )
|
||||||
{
|
{
|
||||||
/* Fast path: */
|
// Fast path:
|
||||||
if( likely( !(*p & 0x80) ) )
|
if( likely( !(*p & 0x80) ) )
|
||||||
{
|
{
|
||||||
if( unlikely(*p >= 'A' && *p <= 'Z') )
|
if( unlikely(*p >= 'A' && *p <= 'Z') )
|
||||||
@@ -1749,7 +1732,7 @@ wstring RStringToWstring( const RString &s )
|
|||||||
char c = s[start];
|
char c = s[start];
|
||||||
if( !(c&0x80) )
|
if( !(c&0x80) )
|
||||||
{
|
{
|
||||||
/* ASCII fast path */
|
// ASCII fast path
|
||||||
ret += c;
|
ret += c;
|
||||||
++start;
|
++start;
|
||||||
continue;
|
continue;
|
||||||
@@ -1774,7 +1757,6 @@ RString WStringToRString( const wstring &sStr )
|
|||||||
return sRet;
|
return sRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RString WcharToUTF8( wchar_t c )
|
RString WcharToUTF8( wchar_t c )
|
||||||
{
|
{
|
||||||
RString ret;
|
RString ret;
|
||||||
@@ -1782,7 +1764,7 @@ RString WcharToUTF8( wchar_t c )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* &a; -> a */
|
// &a; -> a
|
||||||
void ReplaceEntityText( RString &sText, const map<RString,RString> &m )
|
void ReplaceEntityText( RString &sText, const map<RString,RString> &m )
|
||||||
{
|
{
|
||||||
RString sRet;
|
RString sRet;
|
||||||
@@ -1793,7 +1775,7 @@ void ReplaceEntityText( RString &sText, const map<RString,RString> &m )
|
|||||||
size_t iStart = sText.find( '&', iOffset );
|
size_t iStart = sText.find( '&', iOffset );
|
||||||
if( iStart == sText.npos )
|
if( iStart == sText.npos )
|
||||||
{
|
{
|
||||||
/* Optimization: if we didn't replace anything at all, do nothing. */
|
// Optimization: if we didn't replace anything at all, do nothing.
|
||||||
if( iOffset == 0 )
|
if( iOffset == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1810,8 +1792,7 @@ void ReplaceEntityText( RString &sText, const map<RString,RString> &m )
|
|||||||
size_t iEnd = sText.find_first_of( "&;", iStart+1 );
|
size_t iEnd = sText.find_first_of( "&;", iStart+1 );
|
||||||
if( iEnd == sText.npos || sText[iEnd] == '&' )
|
if( iEnd == sText.npos || sText[iEnd] == '&' )
|
||||||
{
|
{
|
||||||
/* & with no matching ;, or two & in a row. Append the & and
|
// & with no matching ;, or two & in a row. Append the & and continue.
|
||||||
* continue. */
|
|
||||||
sRet.append( sText, iStart, 1 );
|
sRet.append( sText, iStart, 1 );
|
||||||
++iOffset;
|
++iOffset;
|
||||||
continue;
|
continue;
|
||||||
@@ -1836,7 +1817,7 @@ void ReplaceEntityText( RString &sText, const map<RString,RString> &m )
|
|||||||
sText = sRet;
|
sText = sRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* abcd -> &a; &b; &c; &d; */
|
// abcd -> &a; &b; &c; &d;
|
||||||
void ReplaceEntityText( RString &sText, const map<char,RString> &m )
|
void ReplaceEntityText( RString &sText, const map<char,RString> &m )
|
||||||
{
|
{
|
||||||
RString sFind;
|
RString sFind;
|
||||||
@@ -1852,7 +1833,7 @@ void ReplaceEntityText( RString &sText, const map<char,RString> &m )
|
|||||||
size_t iStart = sText.find_first_of( sFind, iOffset );
|
size_t iStart = sText.find_first_of( sFind, iOffset );
|
||||||
if( iStart == sText.npos )
|
if( iStart == sText.npos )
|
||||||
{
|
{
|
||||||
/* Optimization: if we didn't replace anything at all, do nothing. */
|
// Optimization: if we didn't replace anything at all, do nothing.
|
||||||
if( iOffset == 0 )
|
if( iOffset == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1880,13 +1861,13 @@ void ReplaceEntityText( RString &sText, const map<char,RString> &m )
|
|||||||
sText = sRet;
|
sText = sRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Replace &#nnnn; (decimal) and &xnnnn; (hex) with corresponding UTF-8 characters. */
|
// Replace &#nnnn; (decimal) and &xnnnn; (hex) with corresponding UTF-8 characters.
|
||||||
void Replace_Unicode_Markers( RString &sText )
|
void Replace_Unicode_Markers( RString &sText )
|
||||||
{
|
{
|
||||||
unsigned iStart = 0;
|
unsigned iStart = 0;
|
||||||
while( iStart < sText.size() )
|
while( iStart < sText.size() )
|
||||||
{
|
{
|
||||||
/* Look for &#digits; */
|
// Look for &#digits;
|
||||||
bool bHex = false;
|
bool bHex = false;
|
||||||
size_t iPos = sText.find( "&#", iStart );
|
size_t iPos = sText.find( "&#", iStart );
|
||||||
if( iPos == sText.npos )
|
if( iPos == sText.npos )
|
||||||
@@ -1902,19 +1883,19 @@ void Replace_Unicode_Markers( RString &sText )
|
|||||||
unsigned p = iPos;
|
unsigned p = iPos;
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
/* Found &# or &x. Is it followed by digits and a semicolon? */
|
// Found &# or &x. Is it followed by digits and a semicolon?
|
||||||
if( p >= sText.size() )
|
if( p >= sText.size() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int iNumDigits = 0;
|
int iNumDigits = 0;
|
||||||
while( p < sText.size() && bHex? isxdigit(sText[p]):isdigit(sText[p]) )
|
while( p < sText.size() && bHex? isxdigit(sText[p]):isdigit(sText[p]) )
|
||||||
{
|
{
|
||||||
p++;
|
p++;
|
||||||
iNumDigits++;
|
iNumDigits++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !iNumDigits )
|
if( !iNumDigits )
|
||||||
continue; /* must have at least one digit */
|
continue; // must have at least one digit
|
||||||
if( p >= sText.size() || sText[p] != ';' )
|
if( p >= sText.size() || sText[p] != ';' )
|
||||||
continue;
|
continue;
|
||||||
p++;
|
p++;
|
||||||
@@ -1931,7 +1912,7 @@ void Replace_Unicode_Markers( RString &sText )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Form a string to identify a wchar_t with ASCII. */
|
// Form a string to identify a wchar_t with ASCII.
|
||||||
RString WcharDisplayText( wchar_t c )
|
RString WcharDisplayText( wchar_t c )
|
||||||
{
|
{
|
||||||
RString sChr;
|
RString sChr;
|
||||||
@@ -1960,8 +1941,7 @@ RString Basename( const RString &sDir )
|
|||||||
return sDir.substr( iStart, iEnd-iStart+1 );
|
return sDir.substr( iStart, iEnd-iStart+1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Return all but the last named component of dir:
|
||||||
* Return all but the last named component of dir:
|
|
||||||
*
|
*
|
||||||
* a/b/c -> a/b/
|
* a/b/c -> a/b/
|
||||||
* a/b/c/ -> a/b/
|
* a/b/c/ -> a/b/
|
||||||
@@ -1971,16 +1951,16 @@ RString Basename( const RString &sDir )
|
|||||||
*/
|
*/
|
||||||
RString Dirname( const RString &dir )
|
RString Dirname( const RString &dir )
|
||||||
{
|
{
|
||||||
/* Special case: "/" -> "/". */
|
// Special case: "/" -> "/".
|
||||||
if( dir.size() == 1 && dir[0] == '/' )
|
if( dir.size() == 1 && dir[0] == '/' )
|
||||||
return "/";
|
return "/";
|
||||||
|
|
||||||
int pos = dir.size()-1;
|
int pos = dir.size()-1;
|
||||||
/* Skip trailing slashes. */
|
// Skip trailing slashes.
|
||||||
while( pos >= 0 && dir[pos] == '/' )
|
while( pos >= 0 && dir[pos] == '/' )
|
||||||
--pos;
|
--pos;
|
||||||
|
|
||||||
/* Skip the last component. */
|
// Skip the last component.
|
||||||
while( pos >= 0 && dir[pos] != '/' )
|
while( pos >= 0 && dir[pos] != '/' )
|
||||||
--pos;
|
--pos;
|
||||||
|
|
||||||
@@ -2050,8 +2030,7 @@ void FixSlashesInPlace( RString &sPath )
|
|||||||
sPath[i] = '/';
|
sPath[i] = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Keep trailing slashes, since that can be used to illustrate that a path always
|
||||||
* Keep trailing slashes, since that can be used to illustrate that a path always
|
|
||||||
* represents a directory.
|
* represents a directory.
|
||||||
*
|
*
|
||||||
* foo/bar -> foo/bar
|
* foo/bar -> foo/bar
|
||||||
@@ -2075,7 +2054,7 @@ void CollapsePath( RString &sPath, bool bRemoveLeadingDot )
|
|||||||
size_t iNext;
|
size_t iNext;
|
||||||
for( ; iPos < sPath.size(); iPos = iNext )
|
for( ; iPos < sPath.size(); iPos = iNext )
|
||||||
{
|
{
|
||||||
/* Find the next slash. */
|
// Find the next slash.
|
||||||
iNext = sPath.find( '/', iPos );
|
iNext = sPath.find( '/', iPos );
|
||||||
if( iNext == RString::npos )
|
if( iNext == RString::npos )
|
||||||
iNext = sPath.size();
|
iNext = sPath.size();
|
||||||
@@ -2089,32 +2068,32 @@ void CollapsePath( RString &sPath, bool bRemoveLeadingDot )
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is a dot, skip it. */
|
// If this is a dot, skip it.
|
||||||
if( iNext - iPos == 2 && sPath[iPos] == '.' && sPath[iPos+1] == '/' )
|
if( iNext - iPos == 2 && sPath[iPos] == '.' && sPath[iPos+1] == '/' )
|
||||||
{
|
{
|
||||||
if( bRemoveLeadingDot || !sOut.empty() )
|
if( bRemoveLeadingDot || !sOut.empty() )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is two dots, */
|
// If this is two dots,
|
||||||
if( iNext - iPos == 3 && sPath[iPos] == '.' && sPath[iPos+1] == '.' && sPath[iPos+2] == '/' )
|
if( iNext - iPos == 3 && sPath[iPos] == '.' && sPath[iPos+1] == '.' && sPath[iPos+2] == '/' )
|
||||||
{
|
{
|
||||||
/* If this is the first path element (nothing to delete), or all we have is a slash,
|
/* If this is the first path element (nothing to delete),
|
||||||
* leave it. */
|
* or all we have is a slash, leave it. */
|
||||||
if( sOut.empty() || (sOut.size() == 1 && sOut[0] == '/') )
|
if( sOut.empty() || (sOut.size() == 1 && sOut[0] == '/') )
|
||||||
{
|
{
|
||||||
sOut.append( sPath, iPos, iNext-iPos );
|
sOut.append( sPath, iPos, iNext-iPos );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search backwards for the previous path element. */
|
// Search backwards for the previous path element.
|
||||||
size_t iPrev = sOut.rfind( '/', sOut.size()-2 );
|
size_t iPrev = sOut.rfind( '/', sOut.size()-2 );
|
||||||
if( iPrev == RString::npos )
|
if( iPrev == RString::npos )
|
||||||
iPrev = 0;
|
iPrev = 0;
|
||||||
else
|
else
|
||||||
++iPrev;
|
++iPrev;
|
||||||
|
|
||||||
/* If the previous element is also .., leave it. */
|
// If the previous element is also .., leave it.
|
||||||
bool bLastIsTwoDots = (sOut.size() - iPrev == 3 && sOut[iPrev] == '.' && sOut[iPrev+1] == '.' );
|
bool bLastIsTwoDots = (sOut.size() - iPrev == 3 && sOut[iPrev] == '.' && sOut[iPrev+1] == '.' );
|
||||||
if( bLastIsTwoDots )
|
if( bLastIsTwoDots )
|
||||||
{
|
{
|
||||||
@@ -2269,6 +2248,7 @@ LuaFunction( Uppercase, MakeUpper( SArg(1) ) )
|
|||||||
LuaFunction( mbstrlen, (int)RStringToWstring(SArg(1)).length() )
|
LuaFunction( mbstrlen, (int)RStringToWstring(SArg(1)).length() )
|
||||||
LuaFunction( URLEncode, URLEncode( SArg(1) ) );
|
LuaFunction( URLEncode, URLEncode( SArg(1) ) );
|
||||||
//LuaFunction( IsHexVal, IsHexVal( SArg(1) ) );
|
//LuaFunction( IsHexVal, IsHexVal( SArg(1) ) );
|
||||||
|
LuaFunction( UndocumentedFeature, sm_crash(SArg(1)) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2005 Chris Danford, Glenn Maynard
|
* Copyright (c) 2001-2005 Chris Danford, Glenn Maynard
|
||||||
|
|||||||
Reference in New Issue
Block a user