X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Flibc.c;h=b0c083b02ac7b9a4d01dbfc4c0aab615c30b78b2;hb=c8f8642db99f495f7baa098ba0169848bc411124;hp=08ebc623d0b81706342a789248d4fc2c2e9f4c25;hpb=31037f330a0fc04936a4a1c608e7fd8d377dea89;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/libc.c b/KernelLand/Kernel/libc.c index 08ebc623..b0c083b0 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 @@ -16,6 +17,10 @@ // === PROTOTYPES === #if 0 +unsigned long long strtoull(const char *str, char **end, int base); +unsigned long strtoul(const char *str, char **end, int base); +signed long long strtoll(const char *str, char **end, int base); +signed long strtol(const char *str, char **end, int base); int atoi(const char *string); int ParseInt(const char *string, int *Val); void itoa(char *buf, Uint64 num, int base, int minLength, char pad); @@ -49,6 +54,7 @@ EXPORT(tolower); EXPORT(strucmp); EXPORT(strchr); +EXPORT(strrchr); EXPORT(strpos); EXPORT(strlen); EXPORT(strcpy); @@ -66,15 +72,10 @@ EXPORT(CheckString); EXPORT(CheckMem); // === CODE === -/** - * \brief Convert a string into an integer - */ -int atoi(const char *string) -{ - int ret = 0; - ParseInt(string, &ret); - return ret; -} +// - Import userland stroi.c file +#define _LIB_H_ +#include "../../Usermode/Libraries/libc.so_src/strtoi.c" + int ParseInt(const char *string, int *Val) { int ret = 0; @@ -167,6 +168,8 @@ void itoa(char *buf, Uint64 num, int base, int minLength, char pad) // Convert while(num > base-1) { num = DivMod64U(num, base, &rem); // Shift `num` and get remainder + ASSERT(rem >= 0); + ASSERT(rem < base); tmpBuf[pos] = cUCDIGITS[ rem ]; pos++; } @@ -183,7 +186,14 @@ void itoa(char *buf, Uint64 num, int base, int minLength, char pad) /** * \brief Append a character the the vsnprintf output */ -#define PUTCH(c) _putch(c) +#define PUTCH(ch) do { \ + if(pos < __maxlen) { \ + if(__s) __s[pos] = ch; \ + } else { \ + (void)ch;\ + } \ + pos ++; \ + } while(0) #define GETVAL() do {\ if(isLongLong) val = va_arg(args, Uint64);\ else val = va_arg(args, unsigned int);\ @@ -197,22 +207,11 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) 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 int bPadLeft = 0; - - auto void _putch(char ch); - - void _putch(char ch) - { - if(pos < __maxlen) - { - if(__s) __s[pos] = ch; - } - pos ++; - } while((c = *__format++) != 0) { @@ -229,11 +228,20 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) if(c == 'p') { Uint ptr = va_arg(args, Uint); PUTCH('*'); PUTCH('0'); PUTCH('x'); - for( len = BITS/4; len --; ) - PUTCH( cUCDIGITS[ (ptr>>(len*4))&15 ] ); + for( len = BITS/4; len -- && ((ptr>>(len*4))&15) == 0; ) + ; + len ++; + if( len == 0 ) + PUTCH( '0' ); + else + while( len -- ) + PUTCH( cUCDIGITS[ (ptr>>(len*4))&15 ] ); continue ; } - + + isLongLong = 0; + isLong = 0; + // - Padding Side Flag if(c == '-') { bPadLeft = 1; @@ -291,6 +299,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++; @@ -354,13 +363,25 @@ 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 printString: if(!p) p = "(null)"; len = strlen(p); if( !bPadLeft ) while(len++ < minSize) PUTCH(pad); - while(*p && precision--) PUTCH(*p++); + while(*p && precision--) { PUTCH(*p); p++;} if( bPadLeft ) while(len++ < minSize) PUTCH(pad); break; @@ -368,7 +389,10 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) p = va_arg(args, char*); if( !CheckMem(p, minSize) ) continue; // No #PFs please if(!p) goto printString; - while(minSize--) PUTCH(*p++); + while(minSize--) { + PUTCH(*p); + p ++; + } break; // Single Character @@ -484,7 +508,7 @@ int isspace(int c) } int isupper(int c) { - return ('a' <= c && c <= 'z'); + return ('A' <= c && c <= 'Z'); } int isxdigit(int c) { @@ -529,6 +553,15 @@ char *strchr(const char *__s, int __c) return NULL; } +char *strrchr(const char *__s, int __c) +{ + size_t ofs = strlen(__s); + while(--ofs && __s[ofs] != __c); + if( __s[ofs] == __c ) + return (char*)__s + ofs; + return NULL; +} + /** * \fn int strpos(const char *Str, char Ch) * \brief Search a string for an ascii character @@ -732,7 +765,8 @@ void *memmove(void *__dest, const void *__src, size_t len) } -// NOTE: Strictly not libc, but lib.c is used by userland code too +// NOTE: Strictly not libc, but lib.c is used by userland code too and hence these two +// can't be in it. /** * \name Memory Validation * \{