X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Flib.c;h=bc32a0ce8bf60a8b55e8ee5b00aea43526672304;hb=4e949acb1c98bc071af2d5d9038b4a3e703bf33d;hp=116dce6150a6db8b1302ce69b782207c148c0fa5;hpb=b98fbd4e9c71447d81fc9bd643fb174c76346e0f;p=tpg%2Facess2.git diff --git a/Kernel/lib.c b/Kernel/lib.c index 116dce61..bc32a0ce 100644 --- a/Kernel/lib.c +++ b/Kernel/lib.c @@ -8,7 +8,7 @@ #define RANDOM_SEED 0xACE55052 #define RANDOM_A 0x00731ADE #define RANDOM_C 12345 -#define RANDOM_SPRUCE 0xf12b02b +#define RANDOM_SPRUCE 0xf12b039 // Jan Feb Mar Apr May Jun Jul Aug Sept Oct Nov Dec const short DAYS_BEFORE[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; #define UNIX_TO_2K ((30*365*3600*24) + (7*3600*24)) //Normal years + leap years @@ -20,6 +20,7 @@ void itoa(char *buf, Uint num, int base, int minLength, char pad); int sprintf(char *__s, const char *__format, ...); int tolower(int c); int strucmp(const char *Str1, const char *Str2); +char *strchr(const char *__s, int __c); int strpos(const char *Str, char Ch); Uint8 ByteSum(void *Ptr, int Size); size_t strlen(const char *__s); @@ -27,18 +28,23 @@ char *strcpy(char *__str1, const char *__str2); char *strncpy(char *__str1, const char *__str2, size_t max); int strcmp(const char *str1, const char *str2); int strncmp(const char *str1, const char *str2, size_t num); -char *strdup(const char *Str); +char *_strdup(const char *File, int Line, const char *Str); char **str_split(const char *__str, char __ch); int strpos8(const char *str, Uint32 Search); int ReadUTF8(Uint8 *str, Uint32 *Val); int WriteUTF8(Uint8 *str, Uint32 Val); + int DivUp(int num, int dem); Sint64 timestamp(int sec, int mins, int hrs, int day, int month, int year); -Uint rand(void); + int rand(void); + int CheckString(char *String); int CheckMem(void *Mem, int NumBytes); + int ModUtil_LookupString(char **Array, char *Needle); int ModUtil_SetIdent(char *Dest, char *Value); + + int UnHex(Uint8 *Dest, size_t DestSize, const char *SourceString); // === EXPORTS === EXPORT(atoi); @@ -47,6 +53,7 @@ EXPORT(vsnprintf); EXPORT(sprintf); EXPORT(tolower); EXPORT(strucmp); +EXPORT(strchr); EXPORT(strpos); EXPORT(ByteSum); EXPORT(strlen); @@ -54,7 +61,8 @@ EXPORT(strcpy); EXPORT(strncpy); EXPORT(strcmp); EXPORT(strncmp); -EXPORT(strdup); +//EXPORT(strdup); +EXPORT(_strdup); // Takes File/Line too EXPORT(str_split); EXPORT(strpos8); EXPORT(DivUp); @@ -65,9 +73,7 @@ EXPORT(CheckString); EXPORT(CheckMem); EXPORT(ModUtil_LookupString); EXPORT(ModUtil_SetIdent); - -// === GLOBALS === -static Uint giRandomState = RANDOM_SEED; +EXPORT(UnHex); // === CODE === /** @@ -180,6 +186,13 @@ void itoa(char *buf, Uint num, int base, int minLength, char pad) if(pos==__maxlen){return pos;}\ if(__s){__s[pos++]=ch;}else{pos++;}\ }while(0) +#define GETVAL() do {\ + if(isLongLong) val = va_arg(args, Uint64);\ + else val = va_arg(args, unsigned int);\ + }while(0) +/** + * \brief VArg String Number Print Formatted + */ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) { char c, pad = ' '; @@ -214,9 +227,6 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) goto printString; } - // Get Argument - val = va_arg(args, Uint); - // - Padding Side Flag if(c == '+') { bPadLeft = 1; @@ -232,9 +242,8 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) pad = ' '; // - Minimum length - if(c == '*') { - minSize = val; - val = va_arg(args, Uint); + if(c == '*') { // Dynamic length + minSize = va_arg(args, unsigned int); c = *__format++; } else if('1' <= c && c <= '9') @@ -256,9 +265,6 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) { c = *__format++; if(c == 'l') { - #if BITS == 32 - val |= (Uint64)va_arg(args, Uint) << 32; - #endif c = *__format++; isLongLong = 1; } @@ -270,33 +276,51 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) { case 'd': case 'i': - if( (isLongLong && val >> 63) || (!isLongLong && val >> 31) ) { + GETVAL(); + if( isLongLong && val >> 63 ) { PUTCH('-'); val = -val; } + else if( !isLongLong && val >> 31 ) { + PUTCH('-'); + val = -(Sint32)val; + } itoa(p, val, 10, minSize, pad); goto printString; case 'u': + GETVAL(); itoa(p, val, 10, minSize, pad); goto printString; + case 'X': + if(BITS == 64) + isLongLong = 1; // TODO: Handle non-x86 64-bit archs + GETVAL(); + itoa(p, val, 16, minSize, pad); + goto printString; + case 'x': + GETVAL(); itoa(p, val, 16, minSize, pad); goto printString; case 'o': + GETVAL(); itoa(p, val, 8, minSize, pad); goto printString; case 'b': + GETVAL(); itoa(p, val, 2, minSize, pad); goto printString; case 'B': //Boolean + val = va_arg(args, unsigned int); if(val) p = "True"; else p = "False"; goto printString; // String - Null Terminated Array case 's': - p = (char*)(Uint)val; + p = va_arg(args, char*); // Get Argument + if( !CheckString(p) ) continue; // Avoid #PFs printString: if(!p) p = "(null)"; len = strlen(p); @@ -306,15 +330,16 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) break; case 'C': // Non-Null Terminated Character Array - p = (char*)(Uint)val; + 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++); break; // Single Character case 'c': default: + GETVAL(); PUTCH( (Uint8)val ); break; } @@ -363,6 +388,18 @@ int strucmp(const char *Str1, const char *Str2) return tolower(*Str1) - tolower(*Str2); } +/** + * \brief Locate a byte in a string + */ +char *strchr(const char *__s, int __c) +{ + for( ; *__s; __s ++ ) + { + if( *__s == __c ) return (char*)__s; + } + return NULL; +} + /** * \fn int strpos(const char *Str, char Ch) * \brief Search a string for an ascii character @@ -389,12 +426,12 @@ Uint8 ByteSum(void *Ptr, int Size) } /** - * \fn Uint strlen(const char *__str) + * \fn size_t strlen(const char *__str) * \brief Get the length of string */ -Uint strlen(const char *__str) +size_t strlen(const char *__str) { - Uint ret = 0; + size_t ret = 0; while(*__str++) ret++; return ret; } @@ -448,6 +485,7 @@ int strncmp(const char *Str1, const char *Str2, size_t num) return *Str1-*Str2; } +#if 0 /** * \fn char *strdup(const char *Str) * \brief Duplicates a string @@ -456,9 +494,25 @@ char *strdup(const char *Str) { char *ret; ret = malloc(strlen(Str)+1); + if( !ret ) return NULL; + strcpy(ret, Str); + return ret; +} +#else + +/** + * \fn char *_strdup(const char *File, int Line, const char *Str) + * \brief Duplicates a string + */ +char *_strdup(const char *File, int Line, const char *Str) +{ + char *ret; + ret = Heap_Allocate(File, Line, strlen(Str)+1); + if( !ret ) return NULL; strcpy(ret, Str); return ret; } +#endif /** * \brief Split a string using the passed character @@ -659,7 +713,7 @@ Sint64 timestamp(int sec, int mins, int hrs, int day, int month, int year) ) && month > 1) // Leap year and after feb stamp += 3600*24; - stamp += ((365*4+1) * ((year-2000)&~3)) * 3600*24; // Foour Year Segments + stamp += ((365*4+1) * ((year-2000)&~3)) * 3600*24; // Four Year Segments stamp += ((year-2000)&3) * 365*3600*24; // Inside four year segment stamp += UNIX_TO_2K; @@ -667,27 +721,46 @@ Sint64 timestamp(int sec, int mins, int hrs, int day, int month, int year) } /** - * \fn Uint rand() + * \fn int rand() * \brief Pseudo random number generator - * \note Unknown effectiveness (made up on the spot) */ -Uint rand(void) +int rand(void) { - Uint old = giRandomState; + #if 0 + static Uint state = RANDOM_SEED; + Uint old = state; // Get the next state value - giRandomState = (RANDOM_A*giRandomState + RANDOM_C) & 0xFFFFFFFF; + giRandomState = (RANDOM_A*state + RANDOM_C); // Check if it has changed, and if it hasn't, change it - if(giRandomState == old) giRandomState += RANDOM_SPRUCE; - return giRandomState; + if(state == old) state += RANDOM_SPRUCE; + return state; + #else + // http://en.wikipedia.org/wiki/Xorshift + // 2010-10-03 + static Uint32 x = 123456789; + static Uint32 y = 362436069; + static Uint32 z = 521288629; + static Uint32 w = 88675123; + Uint32 t; + + t = x ^ (x << 11); + x = y; y = z; z = w; + return w = w ^ (w >> 19) ^ t ^ (t >> 8); + #endif } -/// \name Memory Validation -/// \{ +/* * + * \name Memory Validation + * \{ + */ /** * \brief Checks if a string resides fully in valid memory */ int CheckString(char *String) { + if( !MM_GetPhysAddr( (tVAddr)String ) ) + return 0; + // Check 1st page if( MM_IsUser( (tVAddr)String ) ) { @@ -745,7 +818,9 @@ int CheckMem(void *Mem, int NumBytes) } return 0; } -/// \} +/* * + * \} + */ /** * \brief Search a string array for \a Needle @@ -768,3 +843,37 @@ int ModUtil_SetIdent(char *Dest, char *Value) strncpy(Dest, Value, 32); return 1; } + +/** + * \brief Convert a string of hexadecimal digits into a byte stream + */ +int UnHex(Uint8 *Dest, size_t DestSize, const char *SourceString) +{ + int i; + + for( i = 0; i < DestSize*2; i += 2 ) + { + Uint8 val = 0; + + if(SourceString[i] == '\0') break; + + if('0' <= SourceString[i] && SourceString[i] <= '9') + val |= (SourceString[i]-'0') << 4; + else if('A' <= SourceString[i] && SourceString[i] <= 'F') + val |= (SourceString[i]-'A'+10) << 4; + else if('a' <= SourceString[i] && SourceString[i] <= 'f') + val |= (SourceString[i]-'a'+10) << 4; + + if(SourceString[i+1] == '\0') break; + + if('0' <= SourceString[i+1] && SourceString[i+1] <= '9') + val |= (SourceString[i+1] - '0'); + else if('A' <= SourceString[i+1] && SourceString[i+1] <= 'F') + val |= (SourceString[i+1] - 'A' + 10); + else if('a' <= SourceString[i+1] && SourceString[i+1] <= 'f') + val |= (SourceString[i+1] - 'a' + 10); + + Dest[i/2] = val; + } + return i/2; +}