Many changes, bugfixes to user vsnprintf and to escape code handling
[tpg/acess2.git] / Kernel / lib.c
index eea64e0..ab64d67 100644 (file)
@@ -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;
 }
 
@@ -167,14 +183,16 @@ void itoa(char *buf, Uint num, int base, int minLength, char pad)
 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', ...)\n", __s, __maxlen, __format);
+       //Log("vsnprintf: (__s=%p, __maxlen=%i, __format='%s', ...)", __s, __maxlen, __format);
        
        while((c = *__format++) != 0)
        {
@@ -198,8 +216,12 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                
                // Get Argument
                val = va_arg(args, Uint);
-               //Log("val = %x", val);
-
+               
+               // - Padding Side Flag
+               if(c == '+') {
+                       bPadLeft = 1;
+                       c = *__format++;
+               }
                
                // - Padding
                if(c == '0') {
@@ -210,8 +232,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 == '*') {
+                       minSize = val;
+                       val = va_arg(args, Uint);
+                       c = *__format++;
+               }
+               else if('1' <= c && c <= '9')
                {
                        minSize = 0;
                        while('0' <= c && c <= '9')
@@ -221,6 +247,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;
@@ -270,14 +298,17 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                case 's':
                        p = (char*)(Uint)val;
                printString:
-                       //Log("p = '%s'", p);
                        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;
                        if(!p)  goto printString;
+                       //while(minSize--)      PUTCH(*p++);
                        while(minSize--)        PUTCH(*p++);
                        break;
                
@@ -429,6 +460,52 @@ 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';
+                       Log_Debug("Lib", "str_split: ret[%i] = '%s'", j-1, ret[j-1]);
+                       ret[j++] = start;
+               }
+               else {
+                       *start++ = __str[i]; 
+               }
+       }
+       *start = '\0';
+       ret[j] = NULL;
+       Log_Debug("Lib", "str_split: ret[%i] = '%s'", j-1, ret[j-1]);
+       
+       for( j = 0; j < len; j++ )
+               Log_Debug("Lib", "str_split: ret[%i] = '%s'", j, ret[j]);
+       
+       return ret;
+}
+
 /**
  * \fn int DivUp(int num, int dem)
  * \brief Divide two numbers, rounding up

UCC git Repository :: git.ucc.asn.au