X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Flib.c;h=51dbe05843cea18e3f9cf5543297d9b16f8ae6d8;hb=717454930aa0e255517c68c837927deac49bd78e;hp=4fa226c1d3577bde3d678b61f7e1d01061b05f06;hpb=fd042bf66c507e2263492d45b9bad62e1706a4bd;p=tpg%2Facess2.git diff --git a/Kernel/lib.c b/Kernel/lib.c index 4fa226c1..51dbe058 100644 --- a/Kernel/lib.c +++ b/Kernel/lib.c @@ -14,12 +14,16 @@ const short DAYS_BEFORE[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 3 #define UNIX_TO_2K ((30*365*3600*24) + (7*3600*24)) //Normal years + leap years // === PROTOTYPES === +#if 0 int atoi(const char *string); -void itoa(char *buf, Uint num, int base, int minLength, char pad); +void itoa(char *buf, Uint64 num, int base, int minLength, char pad); int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args); int sprintf(char *__s, const char *__format, ...); +#endif int tolower(int c); +#if 0 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 +31,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); +#endif // === EXPORTS === EXPORT(atoi); @@ -47,6 +56,7 @@ EXPORT(vsnprintf); EXPORT(sprintf); EXPORT(tolower); EXPORT(strucmp); +EXPORT(strchr); EXPORT(strpos); EXPORT(ByteSum); EXPORT(strlen); @@ -54,7 +64,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,6 +76,9 @@ EXPORT(CheckString); EXPORT(CheckMem); EXPORT(ModUtil_LookupString); EXPORT(ModUtil_SetIdent); +EXPORT(UnHex); +EXPORT(SwapEndian16); +EXPORT(SwapEndian32); // === CODE === /** @@ -136,12 +150,12 @@ int atoi(const char *string) static const char cUCDIGITS[] = "0123456789ABCDEF"; /** - * \fn void itoa(char *buf, Uint num, int base, int minLength, char pad) + * \fn void itoa(char *buf, Uint64 num, int base, int minLength, char pad) * \brief Convert an integer into a character string */ -void itoa(char *buf, Uint num, int base, int minLength, char pad) +void itoa(char *buf, Uint64 num, int base, int minLength, char pad) { - char tmpBuf[BITS]; + char tmpBuf[64+1]; int pos=0, i; // Sanity check @@ -177,15 +191,19 @@ 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 = ' '; - int minSize = 0, len; + int minSize = 0, precision = -1, len; char tmpBuf[34]; // For Integers - char *p = NULL; + const char *p = NULL; int isLongLong = 0; Uint64 val; size_t pos = 0; @@ -209,16 +227,13 @@ 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'); + itoa(tmpBuf, ptr, 16, BITS/4, '0'); p = tmpBuf; - itoa(p, ptr, 16, BITS/4, '0'); goto printString; } - // Get Argument - val = va_arg(args, unsigned int); - // - Padding Side Flag - if(c == '+') { + if(c == '-') { bPadLeft = 1; c = *__format++; } @@ -233,8 +248,7 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) // - Minimum length if(c == '*') { // Dynamic length - minSize = val; - val = va_arg(args, unsigned int); + minSize = va_arg(args, unsigned int); c = *__format++; } else if('1' <= c && c <= '9') @@ -248,7 +262,28 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) } } else - minSize = 1; + minSize = 0; + + // - Precision + precision = -1; + if( c == '.' ) { + c = *__format++; + + if(c == '*') { // Dynamic length + precision = va_arg(args, unsigned int); + c = *__format++; + } + else if('1' <= c && c <= '9') + { + precision = 0; + while('0' <= c && c <= '9') + { + precision *= 10; + precision += c - '0'; + c = *__format++; + } + } + } // - Default, Long or LongLong? isLongLong = 0; @@ -256,9 +291,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,6 +302,7 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) { case 'd': case 'i': + GETVAL(); if( isLongLong && val >> 63 ) { PUTCH('-'); val = -val; @@ -278,39 +311,53 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) PUTCH('-'); val = -(Sint32)val; } - itoa(p, val, 10, minSize, pad); + itoa(tmpBuf, val, 10, minSize, pad); goto printString; case 'u': - itoa(p, val, 10, minSize, pad); + GETVAL(); + itoa(tmpBuf, val, 10, minSize, pad); goto printString; + case 'X': + if(BITS == 64) + isLongLong = 1; // TODO: Handle non-x86 64-bit archs + GETVAL(); + itoa(tmpBuf, val, 16, minSize, pad); + goto printString; + case 'x': - itoa(p, val, 16, minSize, pad); + GETVAL(); + itoa(tmpBuf, val, 16, minSize, pad); goto printString; case 'o': - itoa(p, val, 8, minSize, pad); + GETVAL(); + itoa(tmpBuf, val, 8, minSize, pad); goto printString; case 'b': - itoa(p, val, 2, minSize, pad); + GETVAL(); + itoa(tmpBuf, 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*)(tVAddr)val; + p = va_arg(args, char*); // Get Argument + if( !CheckString(p) ) p = "(inval)"; // Avoid #PFs printString: if(!p) p = "(null)"; len = strlen(p); if( !bPadLeft ) while(len++ < minSize) PUTCH(pad); - while(*p) PUTCH(*p++); + while(*p && precision--) PUTCH(*p++); if( bPadLeft ) while(len++ < minSize) PUTCH(pad); break; case 'C': // Non-Null Terminated Character Array - p = (char*)(tVAddr)val; + p = va_arg(args, char*); + if( !CheckMem(p, minSize) ) continue; // No #PFs please if(!p) goto printString; while(minSize--) PUTCH(*p++); break; @@ -318,6 +365,7 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) // Single Character case 'c': default: + GETVAL(); PUTCH( (Uint8)val ); break; } @@ -366,6 +414,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 @@ -384,20 +444,21 @@ int strpos(const char *Str, char Ch) * \fn Uint8 ByteSum(void *Ptr, int Size) * \brief Adds the bytes in a memory region and returns the sum */ -Uint8 ByteSum(void *Ptr, int Size) +Uint8 ByteSum(const void *Ptr, int Size) { Uint8 sum = 0; - while(Size--) sum += *(Uint8*)Ptr++; + const Uint8 *data = Ptr; + while(Size--) sum += *(data++); return sum; } /** - * \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; } @@ -451,6 +512,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 @@ -463,6 +525,21 @@ char *strdup(const char *Str) 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 @@ -543,7 +620,7 @@ int strpos8(const char *str, Uint32 Search) * \fn int ReadUTF8(Uint8 *str, Uint32 *Val) * \brief Read a UTF-8 character from a string */ -int ReadUTF8(Uint8 *str, Uint32 *Val) +int ReadUTF8(const Uint8 *str, Uint32 *Val) { *Val = 0xFFFD; // Assume invalid character @@ -671,11 +748,10 @@ 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) { #if 0 static Uint state = RANDOM_SEED; @@ -707,7 +783,7 @@ Uint rand(void) /** * \brief Checks if a string resides fully in valid memory */ -int CheckString(char *String) +int CheckString(const char *String) { if( !MM_GetPhysAddr( (tVAddr)String ) ) return 0; @@ -743,7 +819,7 @@ int CheckString(char *String) /** * \brief Check if a sized memory region is valid memory */ -int CheckMem(void *Mem, int NumBytes) +int CheckMem(const void *Mem, int NumBytes) { tVAddr addr = (tVAddr)Mem; @@ -777,7 +853,7 @@ int CheckMem(void *Mem, int NumBytes) * \brief Search a string array for \a Needle * \note Helper function for eTplDrv_IOCtl::DRV_IOCTL_LOOKUP */ -int ModUtil_LookupString(char **Array, char *Needle) +int ModUtil_LookupString(const char **Array, const char *Needle) { int i; if( !CheckString(Needle) ) return -1; @@ -788,9 +864,52 @@ int ModUtil_LookupString(char **Array, char *Needle) return -1; } -int ModUtil_SetIdent(char *Dest, char *Value) +int ModUtil_SetIdent(char *Dest, const char *Value) { if( !CheckMem(Dest, 32) ) return -1; 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; +} + +Uint16 SwapEndian16(Uint16 Val) +{ + return ((Val&0xFF)<<8) | ((Val>>8)&0xFF); +} +Uint32 SwapEndian32(Uint32 Val) +{ + return ((Val&0xFF)<<24) | ((Val&0xFF00)<<8) | ((Val>>8)&0xFF00) | ((Val>>24)&0xFF); +}