/** @brief Convert the ASCII number pointed to by pachNum to a uint64_t value. The number may be hex or decimal. Hex numbers must be prefixed by '0x', and they may be upper or lower case. The conversion process will stop with the first non hex or decimal digit. If the number is negative (the first character is a '-' sign), the value will be range checked and returned as the equivalent unsigned value. @param pszNum A pointer to the ASCII number to convert. @param pullNum A pointer to the uint64_t location to store the result. This value will be modified on return only if the function succeeds and the returned pointer is valid (not NULL). @return A pointer to the byte following the converted number, or NULL to indicate failure. */ const char *RedNtoULL( const char *pszNum, uint64_t *pullNum) { bool fNegative = false; uint32_t ulIdx = 0U; const char *pszReturn; REDASSERT(pszNum != NULL); REDASSERT(pullNum != NULL); if(pszNum[ulIdx] == '-') { fNegative = true; ulIdx++; } /* Hex numbers must be prefixed with '0x'. */ if((pszNum[ulIdx] == '0') && ((pszNum[ulIdx + 1U] == 'x') || (pszNum[ulIdx + 1U] == 'X'))) { ulIdx += 2U; if(ISDIGIT(pszNum[ulIdx]) || ISHEXDIGIT(pszNum[ulIdx])) { pszReturn = RedHtoULL(&pszNum[ulIdx], pullNum); } else { pszReturn = NULL; } } else if(ISDIGIT(pszNum[ulIdx])) { uint64_t ullTemp = 0U; while(ISDIGIT(pszNum[ulIdx])) { ullTemp *= 10U; ullTemp += pszNum[ulIdx] - '0'; ulIdx++; } if(fNegative) { /* Fail if the number is out of range. */ if(ullTemp > INT64_MAX) { pszReturn = NULL; } else { *pullNum = (uint64_t)(-((int64_t)ullTemp)); pszReturn = &pszNum[ulIdx]; } } else { *pullNum = ullTemp; pszReturn = &pszNum[ulIdx]; } } else { /* Return an error if there is not at least one hex or decimal digit. */ pszReturn = NULL; } return pszReturn; }
int esc( const tchar * * s) { /* Map escape sequences into their equivalent symbols. Return * the equivalent ASCII character. *s is advanced past the * escape sequence. If no escape sequence is present, the * current character is returned and the string is advanced by * one. The following are recognized: * * \b backspace * \f formfeed * \n newline * \r carriage return * \s space * \t tab * \e ASCII ESC character ('\033') * \DDD number formed of 1-3 octal digits * \xDDD number formed of 1-3 hex digits * \^C C = any letter. Control code */ int rval; if( **s != _T('\\') ) rval = *( (*s)++ ); else { ++(*s); /* Skip the \ */ switch( toupper(**s) ) { case _T('\0'): rval = _T('\\'); break; case _T('B'): rval = _T('\b') ; break; case _T('F'): rval = _T('\f') ; break; case _T('N'): rval = _T('\n') ; break; case _T('R'): rval = _T('\r') ; break; case _T('S'): rval = _T(' ') ; break; case _T('T'): rval = _T('\t') ; break; case _T('E'): rval = _T('\033'); break; case _T('^'): rval = *++(*s) ; rval = _toupper(rval) - _T('@') ; break; case _T('X'): rval = 0; ++(*s); if( ISHEXDIGIT(**s) ) { rval = hex2bin( *(*s)++ ); } if( ISHEXDIGIT(**s) ) { rval <<= 4; rval |= hex2bin( *(*s)++ ); } if( ISHEXDIGIT(**s) ) { rval <<= 4; rval |= hex2bin( *(*s)++ ); } --(*s); break; default: if( !ISOCTDIGIT(**s) ) rval = **s; else { ++(*s); rval = oct2bin( *(*s)++ ); if( ISOCTDIGIT(**s) ) { rval <<= 3; rval |= oct2bin( *(*s)++ ); } if( ISOCTDIGIT(**s) ) { rval <<= 3; rval |= oct2bin( *(*s)++ ); } --(*s); } break; } ++(*s); } return rval; }