*/
#include <acess.h>
#include <hal_proc.h> // For MM_*
+#include <utf16.h>
// === CONSTANTS ===
#define RANDOM_SEED 0xACE55052
int pos=0, i;
Uint64 rem;
+ buf[0] = 0;
+ ASSERTR(base >= 2, );
+ ASSERTR(base <= 16, );
+
// Sanity check
if(!buf) return;
- // Sanity Check
- if(base > 16 || base < 2) {
- buf[0] = 0;
- return;
- }
-
// Convert
while(num > base-1) {
num = DivMod64U(num, base, &rem); // Shift `num` and get remainder
+ ASSERT(rem >= 0);
+ if( rem >= base && base != 16 ) {
+ Debug("rem(%llx) >= base(%x), num=%llx", rem, base, num);
+ }
+ ASSERT(rem < base);
tmpBuf[pos] = cUCDIGITS[ rem ];
pos++;
}
* \brief Append a character the the vsnprintf output
*/
#define PUTCH(ch) do { \
- if(pos < __maxlen) { \
- if(__s) __s[pos] = ch; \
+ if(pos < __maxlen && __s) { \
+ __s[pos] = ch; \
} else { \
(void)ch;\
} \
/**
* \brief VArg String Number Print Formatted
*/
-int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
+int vsnprintf(char *__s, const size_t __maxlen, const char *__format, va_list args)
{
char c, pad = ' ';
int minSize = 0, precision = -1, len;
char tmpBuf[34]; // For Integers
const char *p = NULL;
- int isLongLong = 0;
+ int isLongLong = 0, isLong;
Uint64 val;
size_t pos = 0;
// Flags
PUTCH( cUCDIGITS[ (ptr>>(len*4))&15 ] );
continue ;
}
-
+
+ isLongLong = 0;
+ isLong = 0;
+
// - Padding Side Flag
if(c == '-') {
bPadLeft = 1;
isLongLong = 0;
if(c == 'l') // Long is actually the default on x86
{
+ isLong = 1;
c = *__format++;
if(c == 'l') {
c = *__format++;
GETVAL();
if( isLongLong && val >> 63 ) {
PUTCH('-');
- val = -val;
+ if( val == LLONG_MIN )
+ val = LLONG_MAX;
+ else
+ val = -val;
}
- else if( !isLongLong && val >> 31 ) {
+ else if( !isLongLong && (val >> 31) ) {
PUTCH('-');
- val = -(Sint32)val;
+ val = (~val & 0xFFFFFFFF)+1;
}
itoa(tmpBuf, val, 10, minSize, pad);
goto printString;
// String - Null Terminated Array
case 's':
+ if( isLong ) {
+ Uint16 *p16 = va_arg(args, Uint16*);
+ Uint8 tmp[5];
+ while( *p16 && precision-- ) {
+ Uint32 cp;
+ p16 += ReadUTF16(p16, &cp);
+ tmp[WriteUTF8(tmp, cp)] = 0;
+ for(int i = 0; tmp[i] && i<5; i ++)
+ PUTCH(tmp[i]);
+ }
+ break;
+ }
p = va_arg(args, char*); // Get Argument
if( !p || !CheckString(p) ) p = "(inval)"; // Avoid #PFs
printString:
case 'C': // Non-Null Terminated Character Array
p = va_arg(args, char*);
- if( !CheckMem(p, minSize) ) continue; // No #PFs please
+ if( !CheckMem(p, minSize) ) {
+ p = "(inval)";
+ goto printString;
+ }
if(!p) goto printString;
while(minSize--) {
- PUTCH(*p);
+ if(*p == '\0') {
+ PUTCH('\\');
+ PUTCH('0');
+ }
+ else if(*p == '\\') {
+ PUTCH('\\');
+ PUTCH('\\');
+ }
+ else {
+ PUTCH(*p);
+ }
p ++;
}
break;
}
}
- if(__s && pos != __maxlen)
+ if(__s && pos < __maxlen)
__s[pos] = '\0';
return pos;
}
int isupper(int c)
{
- return ('a' <= c && c <= 'z');
+ return ('A' <= c && c <= 'Z');
}
int isxdigit(int c)
{