X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Flib.c;h=cab15b3c758b363fec6af1dc2750e6c50007c112;hb=05e8b329edc7c55eec967c3caba1982c173025e3;hp=62500fe9d40de9e06938bf5f7605767fbae3edb9;hpb=bd8dc898108f10c0498f4dc5d0164a50b5ff2e5c;p=tpg%2Facess2.git diff --git a/Kernel/lib.c b/Kernel/lib.c index 62500fe9..cab15b3c 100644 --- a/Kernel/lib.c +++ b/Kernel/lib.c @@ -28,10 +28,11 @@ 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); - int DivUp(int num, int dem); +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 CheckString(char *String); @@ -54,8 +55,9 @@ EXPORT(strncpy); EXPORT(strcmp); EXPORT(strncmp); EXPORT(strdup); -EXPORT(DivUp); +EXPORT(str_split); EXPORT(strpos8); +EXPORT(DivUp); EXPORT(ReadUTF8); EXPORT(WriteUTF8); EXPORT(timestamp); @@ -74,9 +76,16 @@ static Uint giRandomState = RANDOM_SEED; int atoi(const char *string) { int ret = 0; + int bNeg = 0; + + //Log("atoi: (string='%s')", string); // Clear non-numeric characters - while( !('0' <= *string && *string <= '9') ) string++; + while( !('0' <= *string && *string <= '9') && *string != '-' ) string++; + if( *string == '-' ) { + bNeg = 1; + while( !('0' <= *string && *string <= '9') ) string++; + } if(*string == '0') { @@ -85,32 +94,34 @@ int atoi(const char *string) { // Hex string ++; - for( ;; ) { - ret *= 16; - if('0' <= *string && *string <= '9') + for( ;; string ++ ) + { + if('0' <= *string && *string <= '9') { + ret *= 16; ret += *string - '0'; - else if('A' <= *string && *string <= 'F') + } + else if('A' <= *string && *string <= 'F') { + ret *= 16; ret += *string - 'A' + 10; - else if('a' <= *string && *string <= 'f') + } + else if('a' <= *string && *string <= 'f') { + ret *= 16; ret += *string - 'a' + 10; + } else break; - string ++; } } - else + else // Octal { - for( ;; ) + for( ; '0' <= *string && *string <= '7'; string ++ ) { ret *= 8; - if('0' <= *string && *string <= '7') - ret += *string - '0'; - else - break; + ret += *string - '0'; } } } - else + else // Decimal { for( ; '0' <= *string && *string <= '9'; string++) { @@ -118,6 +129,11 @@ int atoi(const char *string) ret += *string - '0'; } } + + if(bNeg) ret = -ret; + + //Log("atoi: RETURN %i", ret); + return ret; } @@ -156,16 +172,30 @@ void itoa(char *buf, Uint num, int base, int minLength, char pad) buf[i] = 0; } -#define PUTCH(c) do{if(pos==__maxlen)break;if(__s){__s[pos++]=(c);}else{pos++;}}while(0) +/** + * \brief Append a character the the vsnprintf output + */ +#define PUTCH(c) do{\ + char ch=(c);\ + if(pos==__maxlen){return pos;}\ + if(__s){__s[pos++]=ch;}else{pos++;}\ + }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; + int minSize = 0, len; char tmpBuf[34]; // For Integers char *p = NULL; int isLongLong = 0; Uint64 val; size_t pos = 0; + // Flags + int bPadLeft = 0; + + //Log("vsnprintf: (__s=%p, __maxlen=%i, __format='%s', ...)", __s, __maxlen, __format); while((c = *__format++) != 0) { @@ -173,6 +203,7 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) if(c != '%') { PUTCH(c); continue; } c = *__format++; + //Log("pos = %i", pos); // Literal % if(c == '%') { PUTCH('%'); continue; } @@ -189,6 +220,12 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) // Get Argument val = va_arg(args, Uint); + // - Padding Side Flag + if(c == '+') { + bPadLeft = 1; + c = *__format++; + } + // - Padding if(c == '0') { pad = '0'; @@ -198,8 +235,12 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) pad = ' '; // - Minimum length - minSize = 1; - if('1' <= c && c <= '9') + if(c == '*') { // Dynamic length + minSize = val; + val = va_arg(args, Uint); + c = *__format++; + } + else if('1' <= c && c <= '9') { minSize = 0; while('0' <= c && c <= '9') @@ -209,6 +250,8 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) c = *__format++; } } + else + minSize = 1; // - Default, Long or LongLong? isLongLong = 0; @@ -230,10 +273,14 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) { case 'd': case 'i': - if( (isLongLong && val >> 63) || (!isLongLong && val >> 31) ) { + 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': @@ -256,14 +303,17 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) // String - Null Terminated Array case 's': - p = (char*)(Uint)val; + p = (char*)(tVAddr)val; printString: if(!p) p = "(null)"; + len = strlen(p); + if( !bPadLeft ) while(len++ < minSize) PUTCH(pad); while(*p) PUTCH(*p++); + if( bPadLeft ) while(len++ < minSize) PUTCH(pad); break; case 'C': // Non-Null Terminated Character Array - p = (char*)(Uint)val; + p = (char*)(tVAddr)val; if(!p) goto printString; while(minSize--) PUTCH(*p++); break; @@ -274,14 +324,10 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args) PUTCH( (Uint8)val ); break; } - - if(pos == __maxlen) - break; } if(__s && pos != __maxlen) __s[pos] = '\0'; - return pos; } @@ -420,6 +466,47 @@ char *strdup(const char *Str) return ret; } +/** + * \brief Split a string using the passed character + * \return NULL terminated array of strings on the heap + * \param __str String to split + * \param __ch Character to split by + */ +char **str_split(const char *__str, char __ch) +{ + int i, j; + int len = 1; + char **ret; + char *start; + + for( i = 0; __str[i]; i++ ) + { + if(__str[i] == __ch) + len ++; + } + + ret = malloc( sizeof(char*)*(len+1) + (i + 1) ); + if( !ret ) return NULL; + + j = 1; + start = (char *)&ret[len+1]; + ret[0] = start; + for( i = 0; __str[i]; i++ ) + { + if(__str[i] == __ch) { + *start++ = '\0'; + ret[j++] = start; + } + else { + *start++ = __str[i]; + } + } + *start = '\0'; + ret[j] = NULL; + + return ret; +} + /** * \fn int DivUp(int num, int dem) * \brief Divide two numbers, rounding up @@ -578,7 +665,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; @@ -600,13 +687,18 @@ Uint rand(void) return giRandomState; } -/// \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 ) ) { @@ -664,7 +756,9 @@ int CheckMem(void *Mem, int NumBytes) } return 0; } -/// \} +/* * + * \} + */ /** * \brief Search a string array for \a Needle