📄 helper.cpp
字号:
{
int TextLen = strlen( Text );
int iText;
if ( TextLen < NumCharPerLine )
return TextLen; // Line is too short to wrap, so include the whole line.
for ( iText=NumCharPerLine; iText>=0; iText-- )
if ( Text[iText] == ' ' ) // Note: We don't break on dashes (-) because "REG[0013-b4:2]" will wrap funny.
break;
if ( iText < 0 )
return NumCharPerLine; // Found no word break, so just brutally chop text at line boundary.
return iText;
}
char* hztoa( in UInt32 ClockHz, in bool AddUnitType )
{
char* RetVal = GetCircularStr( NULL );
if ( ClockHz > 100000 )
sprintf( RetVal, "%u.%03u MHz", ClockHz/1000000, (ClockHz/1000)%1000 );
else if ( ClockHz > 1000 )
sprintf( RetVal, "%u.%03u KHz", ClockHz/1000, ClockHz%1000 );
else
sprintf( RetVal, "%u Hz", ClockHz );
return RetVal;
}
UInt32 atohz( in const char* Str, in UInt32 DefaultUnit )
{
UInt32 Value = 0;
UInt32 Frac = 0;
int Divisor = -1;
int i;
// Skip beginning spaces.
for ( i=0; Str[i]==' '; i++ )
continue;
for ( ; Str[i]; i++ )
{
switch ( Str[i] )
{
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '0':
if ( Divisor < 0 )
{
Value *= 10;
Value += Str[i]-'0';
}
else
{
Divisor /= 10;
Frac += (Str[i]-'0')*Divisor;
}
break;
case '.':
Divisor = 1000;
break;
// Check for unit type.
case ' ':
switch ( Str[i+1] )
{
case 'M': case 'm': if (Str[i+2]=='H'||Str[i+2]=='h') DefaultUnit=MHZ; break;
case 'K': case 'k': if (Str[i+2]=='H'||Str[i+2]=='h') DefaultUnit=KHZ; break;
case 'H': case 'h': if (Str[i+2]=='Z'||Str[i+2]=='z') DefaultUnit=HZ; break;
}
goto atohzIsDone;
// The user might have forgotten to put a space between "25.175" and "MHz", so just be graceful.
case 'M': case 'm': if (Str[i+1]=='H'||Str[i+1]=='h') DefaultUnit=MHZ; goto atohzIsDone;
case 'K': case 'k': if (Str[i+1]=='H'||Str[i+1]=='h') DefaultUnit=KHZ; goto atohzIsDone;
case 'H': case 'h': if (Str[i+1]=='Z'||Str[i+1]=='z') DefaultUnit=HZ; goto atohzIsDone;
// Unknown character, so just finish up.
default:
goto atohzIsDone;
// Just gobble up and ignore the rest of the string.
atohzIsDone:
while ( Str[i+1] ) i++; // Go to end of string.
break;
}
}
return Value*DefaultUnit + (DefaultUnit>1?Frac*(DefaultUnit/1000):0);
}
void bitpos32( in UInt32 BitField, out int* LeftBit, out int* RightBit )
//
// Given a bitfield mask, this method returns the positions of the first (right-most) ON bit
// and the last (left-most) ON bit. ASSUMPTION: that there are not 2 'ON-bit-sequences' in
// this mask, otherwise only the first sequence will be returned.
// For example, 0000111100111000 will return (3,5).
//
{
int i;
if ( RightBit )
*RightBit = -1;
if ( LeftBit )
*LeftBit = -1;
// Find first 1 bit.
for ( i=0; i<8*sizeof(BitField); i++ )
{
if ( (BitField&0x1) == 1 )
{
if ( RightBit )
*RightBit = i;
break;
}
BitField >>= 1;
}
BitField >>= 1;
// Find last 1 bit.
for ( ; i<8*sizeof(BitField); i++ )
{
if ( (BitField&0x1) == 0 )
{
if ( LeftBit )
*LeftBit = i;
break;
}
BitField >>= 1;
}
}
UInt32 maxbits32( in UInt32 BitFieldMask )
{
int nShift;
bitpos32( BitFieldMask, NULL, &nShift );
return BitFieldMask >> nShift;
}
UInt16 swap16( in UInt16 Value )
{
return (UInt16)( ((Value>>8)&0x00FF) | ((Value&0x00FF)<<8) );
}
UInt32 swap32( in UInt32 Value )
{
return ((Value>>24)&0x00FF) | ((Value>>8)&0xFF00) | ((Value&0xFF00)<<8) | ((Value&0x00FF)<<24);
}
char* strcpynum( out char* Des, in UInt32 Number, in UInt32 Radix, in int SigDigits )
{
switch ( Radix )
{
case 16: // HEXIDECIMAL
sprintf( Des, "%0*X", SigDigits, Number );
break;
case 10: // DECIMAL
sprintf( Des, "%0*u", SigDigits, Number );
break;
case 2: // BINARY
{
int Bit, i=0;
bool NowPrinting = false;
assert( SigDigits>=0 && SigDigits<=32 );
for ( Bit=31; Bit>=0; Bit-- )
{
bool StruckBit = (Number & (1<<Bit)) != 0;
if ( Bit==SigDigits-1 || StruckBit || (Number==0&&SigDigits==0&&Bit==0) )
NowPrinting = true;
if ( NowPrinting )
Des[i++] = ( StruckBit ? '1' : '0' );
}
Des[i] = '\0';
}
break;
default:
assert( false );
break;
}
return Des;
}
char* strcatnum( out char* Des, in UInt32 Number, in UInt32 Radix, in int SigDigits )
{
return strcpynum( Des+strlen(Des), Number, Radix, SigDigits );
}
char* sprintfield( in int FieldWidth, in char* FieldEnd, in char* pszFormat, ... )
{
va_list argptr;
int len;
char* pszTemp = GetCircularStr( NULL );
char* pszField = GetCircularStr( NULL );
va_start( argptr, pszFormat );
vsprintf( pszTemp, pszFormat, argptr );
va_end( argptr );
strcat( pszTemp, FieldEnd );
len = sprintf( pszField, "%*s", -FieldWidth, pszTemp );
if ( len > FieldWidth )
strcat( pszField, " " );
return pszField;
}
char* strpre( inout char* Des, in const char* Src )
{
int DesLen = strlen( Des );
int nCopy = strlen( Src );
int i;
// First make room for Src.
Des[DesLen+nCopy] = '\0';
for ( i=DesLen; i>=0; i-- )
Des[i+nCopy] = Des[i];
// Copy over Src.
for ( i=0; i<nCopy; i++ )
Des[i] = Src[i];
return Des;
}
HSTRPOOL CreateCircularStrPool( in int NumStrs, in int DefaultStrSize )
{
// Look for an empty spot.
for ( int i=0; i<MaxStrPools; i++ )
{
if ( StrPool[i] == NULL )
{
StrPool[i] = new StrPoolRec;
StrPool[i]->MaxStrs = NumStrs;
StrPool[i]->StrList = new char*[NumStrs];
StrPool[i]->StrSizes = new int[NumStrs];
for ( int j=0; j<NumStrs; j++ )
{
StrPool[i]->StrList[j] = NULL;
StrPool[i]->StrSizes[j] = 0;
}
StrPool[i]->MinStrSize = (DefaultStrSize==0) ? 1024 : DefaultStrSize;
StrPool[i]->CurStr = 0;
return (HSTRPOOL)(StrPool[i]);
}
}
return NULL;
}
static StrPoolRec* CreateDefCircularStrPool( void )
{
static HSTRPOOL DefaultPool = NULL;
if ( DefaultPool == NULL )
DefaultPool = CreateCircularStrPool( 24, 512 );
return (StrPoolRec*)DefaultPool;
}
void FreeCircularStrPool( in HSTRPOOL hStrPool )
{
StrPoolRec* P = (StrPoolRec*)hStrPool;
if ( P != NULL )
for ( int iP=0; iP<MaxStrPools; iP++ )
if ( P == StrPool[iP] )
FreeOneCircularStrPool( iP );
}
static void FreeAllCircularStrPools( void )
{
for ( int i=0; i<MaxStrPools; i++ )
FreeOneCircularStrPool( i );
}
static void FreeOneCircularStrPool( in int iPool )
{
if ( StrPool[iPool] != NULL )
{
// Free all text-buffers.
for ( int i=0; i<StrPool[iPool]->MaxStrs; i++ )
{
if ( StrPool[iPool]->StrList[i] )
{
delete [] StrPool[iPool]->StrList[i];
StrPool[iPool]->StrList[i] = NULL;
StrPool[iPool]->StrSizes[i] = 0;
}
}
// Free arrays;
delete [] StrPool[iPool]->StrList;
StrPool[iPool]->StrList = NULL;
delete [] StrPool[iPool]->StrSizes;
StrPool[iPool]->StrSizes = NULL;
// Free pool.
delete StrPool[iPool];
StrPool[iPool] = NULL;
}
}
char* GetCircularStr( in HSTRPOOL hStrPool )
{
StrPoolRec* P = (hStrPool==NULL) ? CreateDefCircularStrPool() : (StrPoolRec*)hStrPool;
// Cycle to next text buffer in sequence.
if ( ++P->CurStr >= P->MaxStrs )
P->CurStr = 0;
// Allocate a text buffer, if it's not already done.
if ( P->StrList[P->CurStr] == NULL )
{
P->StrList[P->CurStr] = new char[P->MinStrSize];
P->StrSizes[P->CurStr] = P->MinStrSize;
assert( P->StrList[P->CurStr] );
}
// Set the first character to zero ensuring an empty string.
P->StrList[P->CurStr][0] = '\0';
return P->StrList[P->CurStr];
}
char* GetCircularStrEx( in HSTRPOOL hStrPool, in int SizeRequired )
{
StrPoolRec* P = (hStrPool==NULL) ? CreateDefCircularStrPool() : (StrPoolRec*)hStrPool;
// Cycle to next text buffer in sequence.
if ( ++P->CurStr >= P->MaxStrs )
P->CurStr = 0;
// If the requested size is less than the default size, use the default size.
if ( SizeRequired < P->MinStrSize )
SizeRequired = P->MinStrSize;
assert( SizeRequired > 0 );
// If we've already allocated a buffer, delete it if it's smaller than the requested size,
// or if the buffer size is bigger than the default size. This effectively deletes large
// allocations and returns them to the default allocation.
if ( P->StrSizes[P->CurStr] )
{
if ( P->StrSizes[P->CurStr] < SizeRequired ||
(SizeRequired == P->MinStrSize && P->StrSizes[P->CurStr] > P->MinStrSize) )
{
delete [] P->StrList[P->CurStr];
P->StrList[P->CurStr] = NULL;
P->StrSizes[P->CurStr] = 0;
}
}
// Allocate a text buffer, if it's not already done.
if ( P->StrList[P->CurStr] == NULL )
{
P->StrList[P->CurStr] = new char[SizeRequired];
P->StrSizes[P->CurStr] = SizeRequired;
assert( P->StrList[P->CurStr] );
}
// Set the first character to zero ensuring an empty string.
P->StrList[P->CurStr][0] = '\0';
return P->StrList[P->CurStr];
}
int GetCircularStrSize( in HSTRPOOL hStrPool, in const char* Str )
{
StrPoolRec* P = (hStrPool==NULL) ? CreateDefCircularStrPool() : (StrPoolRec*)hStrPool;
for ( int i=0; i<P->MaxStrs; i++ )
if ( Str == P->StrList[i] )
return P->StrSizes[i];
assert( false );
return 0;
}
bool ParseBooleanString( in const char* szStr )
{
if ( stricmp(szStr,"true" ) ==0 ) return true;
else if( stricmp(szStr,"t" ) ==0 ) return true;
else if( stricmp(szStr,"yes" ) ==0 ) return true;
else if( stricmp(szStr,"y" ) ==0 ) return true;
else if( stricmp(szStr,"enable" ) ==0 ) return true;
else if( stricmp(szStr,"enabled") ==0 ) return true;
else if( stricmp(szStr,"1" ) ==0 ) return true;
else return false;
}
UInt32 aton32min( in const char *Str, in const int StrLen, in UInt32 MinRadix )
{
UInt32 dwRadix;
if( DetectMinRadix(Str,StrLen,&dwRadix)==0 ) return 0;
return aton32(Str,StrLen, dwRadix>MinRadix?dwRadix:MinRadix );
}
UInt16 ParseAccessTypeString( in const char* szStr )
{
UInt16 wRet;
//
if ( stricmp(szStr,"ro" )==0 ) wRet = ACCS_RO;
else if( stricmp(szStr,"read only" )==0 ) wRet = ACCS_RO;
else if( stricmp(szStr,"wo" )==0 ) wRet = ACCS_WO;
else if( stricmp(szStr,"write only")==0 ) wRet = ACCS_WO;
else if( stricmp(szStr,"rs" )==0 ) wRet = ACCS_RESERVED;
else if( stricmp(szStr,"reserved" )==0 ) wRet = ACCS_RESERVED;
else if( stricmp(szStr,"r/w" )==0 ) wRet = ACCS_NORMAL;
else if( stricmp(szStr,"normal" )==0 ) wRet = ACCS_NORMAL;
else wRet = ACCS_INVALID;
//
return wRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -