//===========================================================================// // Purpose : Function definitions for miscellaneous helpful string functions. // // Functions include: // - TC_CompareStrings // - TC_FormatStringCentered // - TC_FormatStringFilled // - TC_FormatStringDateTimeStamp // - TC_ExtractStringSideMode // - TC_ExtractStringTypeMode // - TC_AddStringPrefix // - TC_AddStringPostfix // - TC_stricmp // - TC_strnicmp // //===========================================================================// #include #include #include #include "TCT_Generic.h" #include "TC_StringUtils.h" //===========================================================================// // Function : TC_CompareStrings // Purpose : Compare two strings, returning a negative value if the // 1st string is less than the 2nd string, returning a // positive value if the 1st string is greater than the // 2nd string, and returning a 0 if both strings are the // same. This function correctly handles alphanumeric // strings in the form "xxx[nnn]" or "xxx(nnn)". For // example, the sort order ( "A[1]", "A[11]", "A[2]" ) // results from a generic string compare function, while // the sort order ( "A[1]", "A[2]", "A[11]" ) results from // this compare function. // Author : Jeff Rudolph //---------------------------------------------------------------------------// // Version history // 05/01/12 jeffr : Original //===========================================================================// int TC_CompareStrings( const char* pszStringA, const char* pszStringB ) { // Compare given two strings, but only after testing for a quick // rejection based on 1st character from each given string int i = 0; // Loop until all characters in alphanumeric strings have been compared while ( pszStringA && pszStringB ) { if ( *pszStringA <= '9' && *pszStringA >= '1' && *pszStringB <= '9' && *pszStringB >= '1' ) { // Handle special case when comparing digits from alphanumeric strings // (by design, 'atol( )' reads until 1st non-digit character is found) long lA = atol( pszStringA ); long lB = atol( pszStringB ); if (( lA != LONG_MAX ) && ( lB != LONG_MAX )) { long l = lA - lB; if ( l == 0 ) { // Skip past digits when digits within alphanumeric strings match while ( *pszStringA <= '9' && *pszStringA >= '0' ) { ++pszStringA; } while ( *pszStringB <= '9' && *pszStringB >= '0' ) { ++pszStringB; } } else { // Detected mis-compare between given alphanumeric strings i = ( l > 0 ? 1 : -1 ); break; } } else { i = *pszStringA - *pszStringB; if ( i == 0 ) { // Skip past digits when digits within alphanumeric strings match ++pszStringA; ++pszStringB; continue; } else { // Detected mis-compare between given alphanumeric strings break; } } } else { // Handle case when comparing non-digits from alphanumeric strings i = *pszStringA - *pszStringB; if ( i == 0 ) { // Continue iterating characters in given alphanumeric strings if ( *pszStringA && *pszStringB ) { ++pszStringA; ++pszStringB; } else if ( *pszStringA ) { ++pszStringA; } else if ( *pszStringB ) { ++pszStringB; } else { break; } } else { // Detected mis-compare between given alphanumeric strings break; } } } return( i ); } //===========================================================================// int TC_CompareStrings( const string& srStringA, const string& srStringB ) { const char* pszStringA = srStringA.data( ); const char* pszStringB = srStringB.data( ); return( TC_CompareStrings( pszStringA, pszStringB )); } //===========================================================================// int TC_CompareStrings( const void* pvoidA, const void* pvoidB ) { const char* pszStringA = static_cast< const char* >( pvoidA ); const char* pszStringB = static_cast< const char* >( pvoidB ); return( TC_CompareStrings( pszStringA, pszStringB )); } //===========================================================================// // Function : TC_FormatStringCentered // Purpose : Format and return a centered string based on the given // centered string reference length. // Author : Jeff Rudolph //---------------------------------------------------------------------------// // Version history // 05/01/12 jeffr : Original //===========================================================================// bool TC_FormatStringCentered( const char* pszString, size_t lenRefer, char* pszCentered, size_t lenCentered ) { if ( pszString && pszCentered ) { memset( pszCentered, 0, lenCentered ); size_t lenString = strlen( pszString ); size_t lenBeginSpc = ( lenRefer - lenString ) > 0 ? ( lenRefer - lenString ) / 2 : 0; size_t lenEndSpc = ( lenRefer - lenString + 1 ) > 0 ? ( lenRefer - lenString + 1 ) / 2 : 0; if ( lenCentered >= lenString + lenBeginSpc + lenEndSpc + 1 ) { sprintf( pszCentered, "%*s%s%*s", (int)lenBeginSpc, lenBeginSpc > 0 ? " " : "", pszString, (int)lenEndSpc, lenEndSpc > 0 ? " " : "" ); } } return( pszCentered && *pszCentered ? true : false ); } //===========================================================================// // Function : TC_FormatStringFilled // Purpose : Format and return a filled string based on the given fill // character. // Author : Jeff Rudolph //---------------------------------------------------------------------------// // Version history // 05/01/12 jeffr : Original //===========================================================================// bool TC_FormatStringFilled( char cFill, char* pszFilled, size_t lenFilled ) { if ( pszFilled ) { memset( pszFilled, 0, lenFilled + 1); memset( pszFilled, cFill, lenFilled ); } return( pszFilled && *pszFilled ? true : false ); } //===========================================================================// // Function : TC_FormatStringDateTimeStamp // Purpose : Format and return a date/time stamp string with optional // prefix/postfix strings. // Author : Jeff Rudolph //---------------------------------------------------------------------------// // Version history // 05/01/12 jeffr : Original //===========================================================================// bool TC_FormatStringDateTimeStamp( char* pszDateTimeStamp, size_t lenDateTimeStamp, const char* pszPrefix, const char* pszPostfix ) { if ( pszDateTimeStamp ) { memset( pszDateTimeStamp, 0, lenDateTimeStamp ); time_t gmtTime; time( &gmtTime ); struct tm* localTime = localtime( &gmtTime ); size_t lenPrefix = pszPrefix ? strlen( pszPrefix ) : 0; size_t lenPostfix = pszPostfix ? strlen( pszPostfix ) : 0; if ( lenDateTimeStamp >= 17 + lenPrefix + lenPostfix + 1 ) { sprintf( pszDateTimeStamp, "%s%2d/%2d/%2d %2d:%2d:%2d%s", (pszPrefix == NULL) ? pszPrefix : "", localTime->tm_mon + 1, localTime->tm_mday, localTime->tm_year % 100, localTime->tm_hour, localTime->tm_min, localTime->tm_sec, (pszPostfix == NULL) ? pszPostfix : "" ); } } return( pszDateTimeStamp && *pszDateTimeStamp ? true : false ); } //===========================================================================// // Function : TC_ExtractStringSideMode // Author : Jeff Rudolph //---------------------------------------------------------------------------// // Version history // 05/01/12 jeffr : Original //===========================================================================// void TC_ExtractStringSideMode( TC_SideMode_t sideMode, string* psrSideMode ) { if ( psrSideMode ) { *psrSideMode = ""; switch( sideMode ) { case TC_SIDE_LEFT: *psrSideMode = "left"; break; case TC_SIDE_RIGHT: *psrSideMode = "right"; break; case TC_SIDE_LOWER: *psrSideMode = "lower"; break; case TC_SIDE_UPPER: *psrSideMode = "upper"; break; case TC_SIDE_BOTTOM: *psrSideMode = "bottom"; break; case TC_SIDE_TOP: *psrSideMode = "top"; break; case TC_SIDE_PREV: *psrSideMode = "prev"; break; case TC_SIDE_NEXT: *psrSideMode = "next"; break; default: *psrSideMode = "?"; break; } } } //===========================================================================// // Function : TC_ExtractStringTypeMode // Author : Jeff Rudolph //---------------------------------------------------------------------------// // Version history // 05/01/12 jeffr : Original //===========================================================================// void TC_ExtractStringTypeMode( TC_TypeMode_t typeMode, string* psrTypeMode ) { if ( psrTypeMode ) { *psrTypeMode = ""; switch( typeMode ) { case TC_TYPE_INPUT: *psrTypeMode = "input"; break; case TC_TYPE_OUTPUT: *psrTypeMode = "output"; break; case TC_TYPE_SIGNAL: *psrTypeMode = "signal"; break; case TC_TYPE_CLOCK: *psrTypeMode = "clock"; break; case TC_TYPE_RESET: *psrTypeMode = "reset"; break; case TC_TYPE_POWER: *psrTypeMode = "power"; break; default: *psrTypeMode = "?"; break; } } } //===========================================================================// // Function : TC_AddStringPrefix // Purpose : Add the given prefix to the given string. // Author : Jeff Rudolph //---------------------------------------------------------------------------// // Version history // 05/01/12 jeffr : Original //===========================================================================// bool TC_AddStringPrefix( char* pszString, const char* pszPrefix ) { if ( pszString && pszPrefix ) { size_t lenString = strlen( pszString ); size_t lenPrefix = strlen( pszPrefix ); size_t lenCopy = TCT_Min( lenString, lenPrefix ); memcpy( pszString, pszPrefix, lenCopy ); } return( pszPrefix && *pszPrefix ? true : false ); } //===========================================================================// // Function : TC_AddStringPostfix // Purpose : Add the given postfix to the given string. // Author : Jeff Rudolph //---------------------------------------------------------------------------// // Version history // 05/01/12 jeffr : Original //===========================================================================// bool TC_AddStringPostfix( char* pszString, const char* pszPostfix ) { if ( pszString && pszPostfix ) { size_t lenString = strlen( pszString ); size_t lenPostfix = strlen( pszPostfix ); size_t lenCopy = TCT_Min( lenString, lenPostfix ); memcpy( pszString + lenString - lenCopy, pszPostfix, lenCopy ); } return( pszPostfix && *pszPostfix ? true : false ); } //===========================================================================// // Function : TC_stricmp // Author : Jeff Rudolph //---------------------------------------------------------------------------// // Version history // 05/01/12 jeffr : Original //===========================================================================// int TC_stricmp( const char* pszStringA, const char* pszStringB ) { while (( pszStringA && *pszStringA ) && ( pszStringB && *pszStringB ) && ( toupper( *pszStringA ) == toupper( *pszStringB ))) { pszStringA++; pszStringB++; } return(( !pszStringA && !pszStringA ) ? 0 : ( *pszStringA - *pszStringB )); } //===========================================================================// // Function : TC_strnicmp // Author : Jeff Rudolph //---------------------------------------------------------------------------// // Version history // 05/01/12 jeffr : Original //===========================================================================// int TC_strnicmp( const char* pszStringA, const char* pszStringB, int i ) { while (( pszStringA && *pszStringA ) && ( pszStringB && *pszStringB ) && ( toupper( *pszStringA ) == toupper( *pszStringB )) && ( i )) { pszStringA++; pszStringB++; --i; } pszStringA = ( i > 0 ? pszStringA : 0 ); pszStringB = ( i > 0 ? pszStringB : 0 ); return(( !pszStringA && !pszStringA ) ? 0 : ( *pszStringA - *pszStringB )); }