📄 helper.cpp
字号:
//============================================================================
//
// HELPER.CPP
//
// Copyright (c) 2002 Epson Research and Development, Inc.
// All rights reserved.
//
// The tabs in the file is formatted at 4.
//
//============================================================================
#ifdef _WIN32
#pragma warning( disable : 4100 ) // Disable "unreferenced formal parameter" warning.
#endif
#include <windows.h> // For max()???? Argh! ROC TODO: Talk to DSM about this! [ROC]
#include <string.h>
#include <stdio.h> // For sprintf.
#include <stdarg.h> // For va_arg.
#include <stdlib.h> // For atol.
#include <assert.h>
#include "datatype.h"
#include "helper.h"
static bool IsFirstTime = true;
typedef struct StrPoolRec
{
char* * StrList; // Array of text-buffers.
int* StrSizes; // Array of text-buffer sizes.
int MaxStrs; // Maximum number of text-buffers in the recycle pool.
int MinStrSize; // Maximum size of a text-buffer.
int CurStr; // Index to the current text-buffer.
} StrPoolRec;
static const int MaxStrPools = 8;
static StrPoolRec* StrPool[MaxStrPools];
static StrPoolRec* CreateDefCircularStrPool( void );
static void FreeAllCircularStrPools( void );
static void FreeOneCircularStrPool( in int iPool );
bool HelperInit( void )
{
if ( IsFirstTime )
{
for ( int i=0; i<MaxStrPools; i++ )
StrPool[i] = NULL;
atexit( FreeAllCircularStrPools );
IsFirstTime = false;
}
return true;
}
UInt32 atoi32( in const char *Str, in UInt32 Radix )
{
if ( Str )
return aton32( Str, strlen(Str), Radix );
return 0;
}
UInt32 aton32( in const char *Str, in const int StrLen, in UInt32 Radix )
{
UInt32 RetVal = 0;
bool Finished = false;
int i, Len = StrLen;
//
if( Str == NULL ) return 0;
if( Len == 0 ) Len = strlen( Str );
//
switch ( Radix )
{
case 16: // HEXIDECIMAL
for ( i=0; i<Len && !Finished; i++ )
{
switch ( Str[i] )
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
RetVal = (RetVal<<4) + (Str[i]-'0');
break;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
RetVal = (RetVal<<4) + (Str[i]-'A') + 10;
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
RetVal = (RetVal<<4) + (Str[i]-'a') + 10;
break;
case 'x': case 'X':
if( (i==1) && (Str[i]=='0') ) break;
else Finished = true;
break;
default:
Finished = true;
break;
}
}
break;
case 10: // DECIMAL
for ( i=0; i<Len && !Finished; i++ )
{
switch ( Str[i] )
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
RetVal = (RetVal*10) + (Str[i]-'0');
break;
default:
Finished = true;
break;
}
}
break;
case 2: // BINARY
for ( i=0; i<Len && !Finished; i++ )
{
switch( Str[i] )
{
case '0': case '1':
RetVal = (RetVal<<1) + (Str[i]-'0');
break;
default:
Finished = true;
break;
}
}
break;
default:
assert( false ); // What the hell is this radix?
break;
}
//
return RetVal;
}
bool isradix( in const char *Str, in const int StrLen, in UInt32 Radix )
{
int i;
assert( Str != NULL );
if ( StrLen==0 || Str[0]=='\0' )
return true;
for ( i=0; i<StrLen; i++ )
{
switch ( Str[i] )
{
case '0': case '1':
break;
case '2': case '3': case '4': case '5': case '6': case '7': case '8':
if ( Radix == 2 )
return false;
break;
case '9':
if ( Radix <= 8 )
return false;
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
if ( Radix <= 10 )
return false;
break;
case 'h': // 10h = HEX
if ( Radix!=16 || i!=StrLen-1 )
return false;
break;
case 't': // 10t = DEC
if ( Radix!=10 || i!=StrLen-1 )
return false;
break;
case 'o': // 10o = OCT
if ( Radix!=8 || i!=StrLen-1 )
return false;
break;
case 'i': // 10i = BIN
if ( Radix!=2 || i!=StrLen-1 )
return false;
break;
default:
return false;
break;
}
}
return true;
}
bool DetectMinRadix( in const char *Str, in const int StrLen, out UInt32* Radix )
{
int i,len;
UInt32 dwResult = 2;
bool fForcedRadix = false;
//
if( Str == NULL )
{
assert( false );
return false;
}
//
if( StrLen==0 ) len = strlen( Str );
else len = StrLen;
//
for( i=0; i<len; i++ )
{
switch ( Str[i] )
{
case '0': case '1':
break;
case '2': case '3': case '4': case '5': case '6': case '7':
if( dwResult < 8 ) dwResult = 8;
break;
case '8': case '9':
if( dwResult < 10 ) dwResult = 10;
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
if( dwResult < 16 ) dwResult = 16;
break;
case 'h': // 10h = HEX
if( i!=StrLen-1 ) return false;
else dwResult = 16;
break;
case 't': // 10t = DEC
if( (dwResult>10) || (i!=len-1)) return false;
else dwResult = 10;
break;
case 'o': // 10o = OCT
if( (dwResult>8) || (i!=len-1)) return false;
else
{ dwResult = 8;
fForcedRadix = true;
}
break;
case 'i': // 10i = BIN
if( (dwResult>2) || (i!=len-1)) return false;
else
{ dwResult = 2;
fForcedRadix = true;
}
break;
case 'x': case 'X':
if( (1!=i) || (i==len-1) || (Str[0]!='0') )
return false;
else dwResult = 16;
break;
default:
return false;
break;
}
}
//
if( (fForcedRadix == false) && (dwResult<10) ) dwResult = 10; // Plain numeric string default to decimal.
*Radix = dwResult;
return true;
}
bool isnumber( in const char* Str, in const int StrLen, in UInt32 DefaultRadix, out UInt32* RadixUsed )
//
// This implementation is not efficient nor pretty, but its brute force method works.
//
{
#define TestThisRadix(radix) if (isradix(Str,StrLen,radix)) { if (RadixUsed) *RadixUsed=radix; return true; }
TestThisRadix( DefaultRadix );
// If we got this far, then it didn't work with the DefaultRadix, so we must assume that the number will be suffixed with a radix character.
if ( StrLen < 2 )
return false; // There isn't room for a suffix character.
switch ( Str[StrLen-1] )
{
case 'h': case 'H': TestThisRadix( 16 ); break;
case 't': case 'T': TestThisRadix( 10 ); break;
case 'o': case 'O': TestThisRadix( 8 ); break;
case 'i': case 'I': TestThisRadix( 2 ); break;
}
return false;
}
int strincmp( in const char* Str1, in const char* Str2, in int StrLen )
{
int i;
for ( i=0; i<StrLen; i++ )
{
if ( Str1[i] == '\0' )
return -1;
if ( Str2[i] == '\0' )
return 1;
if ( tolower(Str1[i]) != tolower(Str2[i]) )
return 1;
}
return 0;
}
const char* stristr( in const char* Str, in const char* FindStr )
{
return strinstr( Str, strlen(Str), FindStr, strlen(FindStr) );
}
const char* strinstr( in const char* Str, in int StrLen, in const char* FindStr, in int FindStrLen )
{
int i;
for ( i=0; i<StrLen-FindStrLen+1; i++ )
if ( strincmp(Str+i,FindStr,FindStrLen) == 0 )
return Str+i;
return NULL;
}
char* strellipsis( inout char* Des, in const char* Src, in int SrcLen, in int FieldWidth )
{
bool ApplyEllipsis = ( SrcLen > FieldWidth );
int NumToCopy = ApplyEllipsis ? FieldWidth-3 : SrcLen;
strncpy( Des, Src, NumToCopy );
Des[NumToCopy] = '\0';
if ( ApplyEllipsis )
strcat( Des, "..." );
return Des;
}
int ConvertNLsToCRLFs( inout char* pszText, in int Size )
{
char* pszGet;
char* pszPut;
int i, nNLs;
int len = strlen( pszText );
for ( i=0, nNLs=0; i<len; i++ )
if ( pszText[i]=='\n' && (i==0||pszText[i-1]!='\r') )
nNLs++;
pszGet = &pszText[len];
pszPut = &pszText[len+=nNLs];
assert( len < Size );
while ( nNLs )
{
*pszPut-- = *pszGet;
if ( pszGet[0]=='\n' && (pszGet==pszText||pszGet[-1]!='\r') )
{
*pszPut-- = '\r';
nNLs--;
}
pszGet--;
}
return len;
}
int ConvertCRLFsToNLs( inout char* pszText, in int Size )
{
char* pszGet = pszText;
char* pszPut = pszText;
int len = strlen(pszText) + 1; // Include terminator.
assert( len < Size );
do
{
*pszPut = *pszGet++;
if ( *pszPut != '\r' )
pszPut++;
} while ( --len );
return strlen( pszText );
}
int ConvertCStrToStr( inout char* Text )
{
int iSrc, iDes;
if ( Text == NULL )
return 0;
for ( iSrc=iDes=0; Text[iSrc]; iSrc++,iDes++ )
{
if ( Text[iSrc] == '\\' )
{
iSrc++;
switch ( Text[iSrc] )
{
case '0': Text[iDes] = '\0'; break;
case 'a': Text[iDes] = '\a'; break;
case 'b': Text[iDes] = '\b'; break;
case 'r': Text[iDes] = '\r'; break;
case 'n': Text[iDes] = '\n'; break;
case 't': Text[iDes] = '\t'; break;
default: Text[iDes] = Text[iSrc]; break;
}
}
else
Text[iDes] = Text[iSrc];
}
Text[iDes] = '\0';
return iDes;
}
int DetectWordWrap( in const char* Text, in int NumCharPerLine )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -