#include "cwCommon.h" #include "cwLog.h" #include "cwText.h" #include "cwCommonImpl.h" #include "cwMem.h" namespace cw { const char* _nextWhiteChar( const char* s, bool eosFl ) { if( s == nullptr ) return nullptr; for(; *s; ++s ) if( isspace(*s) ) return s; return eosFl ? s : nullptr; } const char* _nextNonWhiteChar( const char* s, bool eosFl ) { if( s == nullptr ) return nullptr; for(; *s; ++s ) if( !isspace(*s) ) return s; return eosFl ? s : nullptr; } } unsigned cw::textLength( const char* s ) { return s == nullptr ? 0 : strlen(s); } const char* cw::textCopy( char* dst, unsigned dstN, const char* src, unsigned srcN ) { if( dst == nullptr || dstN == 0 ) return nullptr; if( srcN == 0 ) srcN = textLength(src); if( src == nullptr || srcN==0 || dstN==1 ) { dst[0] = 0; } else { assert( dstN >= 2 ); unsigned n = std::min( dstN-1, srcN ); memcpy(dst,src,n); dst[n] = 0; } return dst; } void cw::textToLower( char* s ) { if( s != nullptr ) for(; *s; ++s) *s = std::tolower(*s); } void cw::textToUpper( char* s ) { if( s != nullptr ) for(; *s; ++s) *s = std::toupper(*s); } void cw::textToLower( char* dst, const char* src, unsigned dstN ) { if( src != nullptr && dstN>0 ) { unsigned sn = std::min(dstN,textLength(src)+1); unsigned i; for(i=0; i<sn; ++i) dst[i] = std::tolower( src[i] ); dst[i-1] = 0; } } void cw::textToUpper( char* dst, const char* src, unsigned dstN ) { if( src != nullptr && dstN>0 ) { unsigned sn = std::min(dstN,textLength(src)+1); unsigned i; for(i=0; i<sn; ++i) dst[i] = std::toupper( src[i] ); dst[i-1] = 0; } } int cw::textCompare( const char* s0, const char* s1 ) { if( s0 == nullptr || s1 == nullptr ) return s0==s1 ? 0 : 1; // if both pointers are nullptr then trigger a match return strcmp(s0,s1); } int cw::textCompare( const char* s0, const char* s1, unsigned n) { if( s0 == nullptr || s1 == nullptr ) return s0==s1 ? 0 : 1; // if both pointers are nullptr then trigger a match return strncmp(s0,s1,n); } int cw::textCompareI( const char* s0, const char* s1 ) { char b0N = textLength(s0)+1; char b1N = textLength(s1)+1; char b0[ b0N ]; char b1[ b1N ]; textToLower(b0,s0,b0N); textToLower(b1,s1,b1N); return textCompare(b0,b1); } int cw::textCompareI( const char* s0, const char* s1, unsigned n ) { char b0[ n+1 ]; char b1[ n+1 ]; textToLower(b0,s0,n+1); textToLower(b1,s1,n+1); return textCompare(b0,b1,n); } const char* cw::nextWhiteChar( const char* s ) { return _nextWhiteChar(s,false); } const char* cw::nextWhiteCharEOS( const char* s ) { return _nextWhiteChar(s,true); } const char* cw::nextNonWhiteChar( const char* s ) { return _nextNonWhiteChar(s,false); } const char* cw::nextNonWhiteCharEOS( const char* s ) { return _nextNonWhiteChar(s,true); } char* cw::firstMatchChar( char* s, char c ) { if( s == nullptr ) return nullptr; for(; *s; ++s) if(*s == c) return s; return nullptr; } const char* cw::firstMatchChar( const char* s, char c ) { return firstMatchChar((char*)s,c); } char* cw::lastMatchChar( char* s, char c ) { unsigned sn; if( s == nullptr ) return nullptr; sn = textLength(s); if( sn == 0 ) return nullptr; for(char* s1=s+(sn-1); s<=s1; --s1) if( *s1 == c ) return s1; return nullptr; } const char* cw::lastMatchChar( const char* s, char c ) { return lastMatchChar((char*)s,c); } char* cw::removeTrailingWhitespace( char* s ) { char* s0; unsigned sn; if( s == nullptr ) return nullptr; if((sn = textLength(s)) == 0 ) return s; s0 = s + (sn-1); for(; s0>=s; --s0) { if( !isspace(*s0) ) break; *s0 = 0; } return s; } bool cw::isInteger( const char* s ) { for(; *s; ++s) if(!isdigit(*s)) return false; return true; } bool cw::isReal( const char* s) { unsigned decN = 0; for(; *s; ++s) if( *s == '.' ) { if( ++decN > 1) return false; } else { if(!isdigit(*s)) return false; } return true; } bool cw::isIdentifier( const char* s ) { if( !isalpha(*s) && *s != '_' ) return false; for(++s; *s; ++s) if( !isalnum(*s) && *s != '_' ) return false; return true; } char* cw::textJoin( const char* s0, const char* s1 ) { if( s0 == nullptr && s1 == nullptr ) return nullptr; unsigned s0n = textLength(s0); unsigned s1n = textLength(s1); unsigned sn = s0n + s1n + 1; char* s = mem::alloc<char>(sn+1); s[0] = 0; if( s0 != nullptr ) strcpy(s,mem::duplStr(s0)); if( s0 != nullptr && s1 != nullptr ) strcpy(s + strlen(s0), mem::duplStr(s1) ); return s; } char* cw::textAppend( char* s0, const char* s1 ) { if( s0 == nullptr && s1==nullptr) return nullptr; return mem::appendStr(s0,s1); } unsigned cw::toText( char* buf, unsigned bufN, bool v ) { return toText( buf, bufN, v ? "true" : "false" ); } unsigned cw::toText( char* buf, unsigned bufN, char v ) { return snprintf(buf,bufN, "%c", v ); } unsigned cw::toText( char* buf, unsigned bufN, unsigned char v ) { return snprintf(buf,bufN, "%c", v ); } unsigned cw::toText( char* buf, unsigned bufN, unsigned short v ) { return snprintf(buf,bufN,"%i",v); } unsigned cw::toText( char* buf, unsigned bufN, short v ) { return snprintf(buf,bufN,"%i",v); } unsigned cw::toText( char* buf, unsigned bufN, unsigned int v ) { return snprintf(buf,bufN,"%i",v); } unsigned cw::toText( char* buf, unsigned bufN, int v ) { return snprintf(buf,bufN,"%i",v); } unsigned cw::toText( char* buf, unsigned bufN, unsigned long long v ) { return snprintf(buf,bufN,"%lli",v); } unsigned cw::toText( char* buf, unsigned bufN, long long v ) { return snprintf(buf,bufN,"%lli",v); } unsigned cw::toText( char* buf, unsigned bufN, float v ) { return snprintf(buf,bufN,"%f",v); } unsigned cw::toText( char* buf, unsigned bufN, double v ) { return snprintf(buf,bufN,"%f",v); } unsigned cw::toText( char* buf, unsigned bufN, const char* v ) { if( v == nullptr ) { cwLogError(kInvalidArgRC,"The source string in a call to 'toText()' was null."); return 0; } unsigned i; for(i=0; i<bufN; ++i) { buf[i] = v[i]; if(v[i]==0) return i; // on success return the length of the string in buf[] and v[] } return 0; // if buf is too small return 0 }