X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Flibc.c;h=572184d9bd5a94a05342526ce4f84f763e03861d;hb=3c283c4831c40c14d308a54cefb997832a860bca;hp=751497cde5139d9a2bcd470c34c2f041a9038100;hpb=036de600b62968abe291d596be72122dee5c71a9;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/libc.c b/KernelLand/Kernel/libc.c index 751497cd..572184d9 100644 --- a/KernelLand/Kernel/libc.c +++ b/KernelLand/Kernel/libc.c @@ -7,6 +7,7 @@ */ #include #include // For MM_* +#include // === CONSTANTS === #define RANDOM_SEED 0xACE55052 @@ -73,6 +74,7 @@ EXPORT(CheckMem); // === CODE === // - Import userland stroi.c file #define _LIB_H_ +#define _SysDebug(f,v...) Log_Debug("libc", f ,## v) #include "../../Usermode/Libraries/libc.so_src/strtoi.c" int ParseInt(const char *string, int *Val) @@ -155,18 +157,21 @@ void itoa(char *buf, Uint64 num, int base, int minLength, char pad) 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++; } @@ -184,8 +189,8 @@ void itoa(char *buf, Uint64 num, int base, int minLength, char pad) * \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;\ } \ @@ -198,13 +203,13 @@ void itoa(char *buf, Uint64 num, int base, int minLength, char pad) /** * \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 @@ -235,7 +240,10 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) PUTCH( cUCDIGITS[ (ptr>>(len*4))&15 ] ); continue ; } - + + isLongLong = 0; + isLong = 0; + // - Padding Side Flag if(c == '-') { bPadLeft = 1; @@ -293,6 +301,7 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) isLongLong = 0; if(c == 'l') // Long is actually the default on x86 { + isLong = 1; c = *__format++; if(c == 'l') { c = *__format++; @@ -309,11 +318,14 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) 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; @@ -356,8 +368,20 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) // 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 + if( p && !CheckString(p) ) goto invalString; // Avoid #PFs printString: if(!p) p = "(null)"; len = strlen(p); @@ -365,13 +389,40 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) while(*p && precision--) { PUTCH(*p); p++;} if( bPadLeft ) while(len++ < minSize) PUTCH(pad); break; + invalString: + PUTCH('(');PUTCH('i');PUTCH('n');PUTCH('v');PUTCH('a'); PUTCH('l');PUTCH(':'); + PUTCH('*');PUTCH('0');PUTCH('x'); + val = (tVAddr)p; + for( len = BITS/4; len -- && ((val>>(len*4))&15) == 0; ) + ; + len ++; + if( len == 0 ) + PUTCH( '0' ); + else + while( len -- ) + PUTCH( cUCDIGITS[ (val>>(len*4))&15 ] ); + PUTCH(')'); + break; 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; @@ -385,7 +436,7 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) } } - if(__s && pos != __maxlen) + if(__s && pos < __maxlen) __s[pos] = '\0'; return pos;