Index: trunk/kernel/kern/printk.c
===================================================================
--- trunk/kernel/kern/printk.c	(revision 14)
+++ trunk/kernel/kern/printk.c	(revision 23)
@@ -37,4 +37,147 @@
 extern chdev_t            txt0_chdev;        // allocated in kernel_init.c
 
+/////////////////////////////////////
+uint32_t snprintf( char     * string,
+                   uint32_t   length,
+                   char     * format, ... )
+{
+
+#define TO_STREAM(x) do { string[ps] = (x); ps++; if(ps==length) return -1; } while(0);
+
+    va_list    args;      // printf arguments
+    uint32_t   ps;        // write pointer to the string buffer
+
+    ps = 0;   
+    va_start( args , format );
+
+xprintf_text:
+
+    while ( *format != 0 ) 
+    {
+
+        if (*format == '%')   // copy argument to string
+        {
+            format++;
+            goto xprintf_arguments;
+        }
+        else                  // copy one char to string
+        {
+            TO_STREAM( *format );
+            format++;
+        }
+    }
+
+    va_end( args );
+    
+    // add terminating NUL chracter
+    TO_STREAM( 0 );
+    return ps;
+
+xprintf_arguments:
+
+    {
+        char              buf[30];    // buffer to display one number
+        char *            pbuf;       // pointer on first char to display
+        uint32_t          len = 0;    // number of char to display
+        static const char HexaTab[] = "0123456789ABCDEF";
+        uint32_t          i;
+        
+        // Ignore fields width and precision 
+        for ( ; (*format >= '0' && *format <= '9') || (*format == '.') ; format++ );
+
+        switch (*format) 
+        {
+            case ('c'):             // char conversion 
+            {
+                int val = va_arg( args, int );
+                buf[0] = val;
+                pbuf   = buf;
+                len    = 1;
+                break;
+            }
+            case ('d'):             // decimal signed integer
+            {
+                int val = va_arg( args, int );
+                if (val < 0) 
+                {
+                    TO_STREAM( '-' );
+                    val = -val;
+                }
+                for(i = 0; i < 10; i++) 
+                {
+
+                    buf[9 - i] = HexaTab[val % 10];
+                    if (!(val /= 10)) break;
+                }
+                len =  i + 1;
+                pbuf = &buf[9 - i];
+                break;
+            }
+            case ('u'):             // decimal unsigned integer
+            {
+                uint32_t val = va_arg( args, uint32_t );
+                for(i = 0; i < 10; i++) 
+                {
+                    buf[9 - i] = HexaTab[val % 10];
+                    if (!(val /= 10)) break;
+                }
+                len =  i + 1;
+                pbuf = &buf[9 - i];
+                break;
+            }
+            case ('x'):             // 32 bits hexadecimal 
+            case ('l'):             // 64 bits hexadecimal 
+            {
+                uint32_t       imax;
+                uint64_t val;
+                
+                if ( *format == 'l' )   // 64 bits
+                {
+                    val = va_arg( args, uint64_t);
+                    imax = 16;
+                }
+                else                    // 32 bits
+                {
+                    val = va_arg( args, uint32_t);
+                    imax = 8;
+                }
+                
+                TO_STREAM( '0' );
+                TO_STREAM( 'x' );
+                
+                for(i = 0; i < imax; i++) 
+                {
+                    buf[(imax-1) - i] = HexaTab[val % 16];
+                    if (!(val /= 16))  break;
+                }
+                len =  i + 1;
+                pbuf = &buf[(imax-1) - i];
+                break;
+            }
+            case ('s'):             /* string */
+            {
+                char* str = va_arg( args, char* );
+                while (str[len]) { len++; }
+                pbuf = str;
+                break;
+            }
+            default:       // unsupported argument type
+            {
+                return -1;
+            }
+        }  // end switch on  argument type
+
+        format++;
+
+        // copy argument to string
+        for( i = 0 ; i < len ; i++ )
+        {
+            TO_STREAM( pbuf[i] );
+        }
+        
+        goto xprintf_text;
+    }
+} // end xprintf()
+
 ///////////////////////////////////////////////////////////////////////////////////
 // This static function is called by kernel_printf() to display a string on the
@@ -47,5 +190,5 @@
 ///////////////////////////////////////////////////////////////////////////////////
 // @ channel  : TXT channel.
-// @ busy     : TXT device acces mode.
+// @ busy     : TXT device acces mode (busy waiting if non zero).
 // @ buf      : buffer containing the characters.
 // @ nc       : number of characters.
@@ -66,5 +209,5 @@
 //////////////////////////////////////////////////////////////////////////////////////
 // @ channel   : channel index.
-// @ busy      : TXT device access mode.
+// @ busy      : TXT device access mode (busy waiting if non zero).
 // @ format    : printf like format.
 // @ args      : format arguments.
@@ -267,4 +410,5 @@
 }
 
+
 // Local Variables:
 // tab-width: 4
