Index: Makefile
===================================================================
--- Makefile	(revision 7dd1787643001828803b90e39bfe964bead011fa)
+++ Makefile	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
@@ -134,5 +134,11 @@
 	generic/src/lib/sort.c \
 	generic/src/lib/elf.c \
-	generic/src/debug/print.c \
+	generic/src/debug/printf_core.c \
+	generic/src/debug/printf.c \
+	generic/src/debug/sprintf.c \
+	generic/src/debug/snprintf.c \
+	generic/src/debug/vprintf.c \
+	generic/src/debug/vsprintf.c \
+	generic/src/debug/vsnprintf.c \
 	generic/src/debug/symtab.c \
 	generic/src/time/clock.c \
Index: generic/include/print.h
===================================================================
--- generic/include/print.h	(revision 7dd1787643001828803b90e39bfe964bead011fa)
+++ generic/include/print.h	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
@@ -32,11 +32,5 @@
 #include <arch/types.h>
 #include <synch/spinlock.h>
-
-#define INT8	1
-#define INT16	2
-#define INT32	4
-#define INT64	8
-
-extern int printf(const char *fmt, ...);
+#include <arch/arg.h>
 
 /* We need this address in spinlock to avoid deadlock in deadlock detection */
@@ -45,3 +39,13 @@
 #define EOF (-1)
 
+extern int puts(const char * str);
+
+extern int printf(const char *fmt, ...);
+extern int sprintf(char *str, const char *fmt, ...);
+extern int snprintf(char *str, size_t size, const char *fmt, ...);
+
+extern int vprintf(const char *fmt, va_list ap);
+extern int vsprintf(char *str, const char *fmt, va_list ap);
+extern int vsnprintf(char *str, size_t size, const char *fmt, va_list ap);
+
 #endif
Index: generic/include/printf/printf_core.h
===================================================================
--- generic/include/printf/printf_core.h	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
+++ generic/include/printf/printf_core.h	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PRINTF_CORE_H__
+#define __PRINTF_CORE_H__
+
+#include <typedefs.h>
+#include <arch/arg.h>
+
+/** Structure for specifying output methods for different printf clones. */
+struct printf_spec {
+	/* Output function, returns count of printed characters or EOF */
+	int (*write)(void *, size_t, void *);
+	/* Support data - output stream specification, its state, locks,... */
+	void *data;
+
+};
+
+int printf_core(const char *fmt, struct printf_spec *ps ,va_list ap);
+
+#endif
Index: neric/src/debug/print.c
===================================================================
--- generic/src/debug/print.c	(revision 7dd1787643001828803b90e39bfe964bead011fa)
+++ 	(revision )
@@ -1,699 +1,0 @@
-/*
- * Copyright (C) 2001-2004 Jakub Jermar
- * Copyright (C) 2006 Josef Cejka
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file	print.c
- * @brief	Printing functions.
- */
-
-#include <putchar.h>
-#include <print.h>
-#include <synch/spinlock.h>
-#include <arch/arg.h>
-#include <arch/asm.h>
-
-#include <arch.h>
-
-SPINLOCK_INITIALIZE(printflock);			/**< printf spinlock */
-
-#define __PRINTF_FLAG_PREFIX		0x00000001	/* show prefixes 0x or 0 */
-#define __PRINTF_FLAG_SIGNED		0x00000002	/* signed / unsigned number */
-#define __PRINTF_FLAG_ZEROPADDED	0x00000004	/* print leading zeroes */
-#define __PRINTF_FLAG_LEFTALIGNED	0x00000010	/* align to left */
-#define __PRINTF_FLAG_SHOWPLUS		0x00000020	/* always show + sign */
-#define __PRINTF_FLAG_SPACESIGN		0x00000040	/* print space instead of plus */
-#define __PRINTF_FLAG_BIGCHARS		0x00000080	/* show big characters */
-#define __PRINTF_FLAG_NEGATIVE		0x00000100	/* number has - sign */
-
-#define PRINT_NUMBER_BUFFER_SIZE	(64+5)		/* Buffer big enought for 64 bit number
-							 * printed in base 2, sign, prefix and
-							 * 0 to terminate string.. (last one is only for better testing 
-							 * end of buffer by zero-filling subroutine)
-							 */
-typedef enum {
-	PrintfQualifierByte = 0,
-	PrintfQualifierShort,
-	PrintfQualifierInt,
-	PrintfQualifierLong,
-	PrintfQualifierLongLong,
-	PrintfQualifierNative,
-	PrintfQualifierPointer
-} qualifier_t;
-
-static char digits_small[] = "0123456789abcdef"; 	/* Small hexadecimal characters */
-static char digits_big[] = "0123456789ABCDEF"; 		/* Big hexadecimal characters */
-
-static inline int isdigit(int c)
-{
-	return ((c >= '0' )&&( c <= '9'));
-}
-
-static __native strlen(const char *str) 
-{
-	__native counter = 0;
-
-	while (str[counter] != 0) {
-		counter++;
-	}
-
-	return counter;
-}
-
-/** Print one string without appending newline to the end.
- *
- * Do not use this function directly - printflock is not locked here.
- *
- */
-static int putstr(const char *str)
-{
-	int count;
-	if (str == NULL) {
-		str = "(NULL)";
-	}
-	
-	for (count = 0; str[count] != 0; count++) {
-		putchar(str[count]);
-	}
-	return count;
-}
-
-/** Print count characters from buffer to output.
- *
- * @param buffer Address of the buffer with charaters to be printed.
- * @param count Number of characters to be printed.
- *
- * @return Number of characters printed.
- */
-static int putnchars(const char *buffer, __native count)
-{
-	int i;
-	if (buffer == NULL) {
-		buffer = "(NULL)";
-		count = 6;
-	}
-
-	for (i = 0; i < count; i++) {
-		putchar(buffer[i]);
-	}
-	
-	return count;
-}
-
-/** Print one formatted character
- *
- * @param c Character to print.
- * @param width 
- * @param flags
- * @return Number of printed characters or EOF.
- */
-static int print_char(char c, int width, __u64 flags)
-{
-	int counter = 0;
-	
-	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
-		while (--width > 0) { 	/* one space is consumed by character itself hence the predecrement */
-			/* FIXME: painfully slow */
-			putchar(' ');	
-			++counter;
-		}
-	}
-	
- 	putchar(c);
-	++counter;
-
-	while (--width > 0) { /* one space is consumed by character itself hence the predecrement */
-		putchar(' ');
-		++counter;
-	}
-	
-	return counter;
-}
-
-/** Print one string
- * @param s string
- * @param width 
- * @param precision
- * @param flags
- * @return number of printed characters or EOF
- */
-static int print_string(char *s, int width, int precision, __u64 flags)
-{
-	int counter = 0;
-	__native size;
-
-	if (s == NULL) {
-		return putstr("(NULL)");
-	}
-	
-	size = strlen(s);
-
-	/* print leading spaces */
-
-	if (precision == 0) 
-		precision = size;
-
-	width -= precision;
-	
-	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
-		while (width-- > 0) { 	
-			putchar(' ');	
-			counter++;
-		}
-	}
-
-	while (precision > size) {
-		precision--;
-		putchar(' ');	
-		++counter;
-	}
-	
- 	if (putnchars(s, precision) == EOF) {
-		return EOF;
-	}
-
-	counter += precision;
-
-	while (width-- > 0) {
-		putchar(' ');	
-		++counter;
-	}
-	
-	return ++counter;
-}
-
-
-/** Print number in given base
- *
- * Print significant digits of a number in given
- * base.
- *
- * @param num  Number to print.
- * @param width
- * @param precision
- * @param base Base to print the number in (should
- *             be in range 2 .. 16).
- * @param flags output modifiers
- * @return number of written characters or EOF.
- */
-static int print_number(__u64 num, int width, int precision, int base , __u64 flags)
-{
-	char *digits = digits_small;
-	char d[PRINT_NUMBER_BUFFER_SIZE];	/* this is good enough even for base == 2, prefix and sign */
-	char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1];
-	int size = 0;
-	int number_size; /* size of plain number */
-	int written = 0;
-	char sgn;
-	
-	if (flags & __PRINTF_FLAG_BIGCHARS) 
-		digits = digits_big;	
-	
-	*ptr-- = 0; /* Put zero at end of string */
-
-	if (num == 0) {
-		*ptr-- = '0';
-		size++;
-	} else {
-		do {
-			*ptr-- = digits[num % base];
-			size++;
-		} while (num /= base);
-	}
-
-	number_size = size;
-	
-	/* Collect sum of all prefixes/signs/... to calculate padding and leading zeroes */
-	if (flags & __PRINTF_FLAG_PREFIX) {
-		switch(base) {
-			case 2:	/* Binary formating is not standard, but usefull */
-				size += 2;
-				break;
-			case 8:
-				size++;
-				break;
-			case 16:
-				size += 2;
-				break;
-		}
-	}
-
-	sgn = 0;
-	if (flags & __PRINTF_FLAG_SIGNED) {
-		if (flags & __PRINTF_FLAG_NEGATIVE) {
-			sgn = '-';
-			size++;
-		} else if (flags & __PRINTF_FLAG_SHOWPLUS) {
-				sgn = '+';
-				size++;
-			} else if (flags & __PRINTF_FLAG_SPACESIGN) {
-					sgn = ' ';
-					size++;
-				}
-	}
-
-	if (flags & __PRINTF_FLAG_LEFTALIGNED) {
-		flags &= ~__PRINTF_FLAG_ZEROPADDED;
-	}
-
-	/* if number is leftaligned or precision is specified then zeropadding is ignored */
-	if (flags & __PRINTF_FLAG_ZEROPADDED) {
-		if ((precision == 0) && (width > size)) {
-			precision = width - size + number_size;
-		}
-	}
-
-	/* print leading spaces */
-	if (number_size > precision) /* We must print whole number not only a part */
-		precision = number_size;
-
-	width -= precision + size - number_size;
-	
-	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
-		while (width-- > 0) { 	
-			putchar(' ');	
-			written++;
-		}
-	}
-	
-	/* print sign */
-	if (sgn) {
-		putchar(sgn);
-		written++;
-	}
-	
-	/* print prefix */
-	
-	if (flags & __PRINTF_FLAG_PREFIX) {
-		switch(base) {
-			case 2:	/* Binary formating is not standard, but usefull */
-				putchar('0');
-				if (flags & __PRINTF_FLAG_BIGCHARS) {
-					putchar('B');
-				} else {
-					putchar('b');
-				}
-				written += 2;
-				break;
-			case 8:
-				putchar('o');
-				written++;
-				break;
-			case 16:
-				putchar('0');
-				if (flags & __PRINTF_FLAG_BIGCHARS) {
-					putchar('X');
-				} else {
-					putchar('x');
-				}
-				written += 2;
-				break;
-		}
-	}
-
-	/* print leading zeroes */
-	precision -= number_size;
-	while (precision-- > 0) { 	
-		putchar('0');	
-		written++;
-	}
-
-	
-	/* print number itself */
-
-	written += putstr(++ptr);
-	
-	/* print ending spaces */
-	
-	while (width-- > 0) { 	
-		putchar(' ');	
-		written++;
-	}
-
-	return written;
-}
-
-/** Print formatted string.
- *
- * Print string formatted according to the fmt parameter
- * and variadic arguments. Each formatting directive
- * must have the following form:
- * 
- * 	\% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION
- *
- * FLAGS:@n
- * "#"	Force to print prefix.
- * 	For conversion \%o the prefix is 0, for %x and \%X prefixes are 0x and 0X
- *	and for conversion \%b the prefix is 0b.
- *
- * "-"	Align to left.
- *
- * "+"	Print positive sign just as negative.
- *
- * " "	If the printed number is positive and "+" flag is not set, print space in
- *	place of sign.
- *
- * "0"	Print 0 as padding instead of spaces. Zeroes are placed between sign and the
- *	rest of the number. This flag is ignored if "-" flag is specified.
- * 
- * WIDTH:@n
- * Specify minimal width of printed argument. If it is bigger, width is ignored.
- * If width is specified with a "*" character instead of number, width is taken from
- * parameter list. And integer parameter is expected before parameter for processed
- * conversion specification. If this value is negative its absolute value is taken
- * and the "-" flag is set.
- *
- * PRECISION:@n
- * Value precision. For numbers it specifies minimum valid numbers.
- * Smaller numbers are printed with leading zeroes. Bigger numbers are not affected.
- * Strings with more than precision characters are cut off.
- * Just as with width, an "*" can be used used instead of a number.
- * An integer value is then expected in parameters. When both width and precision
- * are specified using "*", the first parameter is used for width and the second one
- * for precision.
- * 
- * TYPE:@n
- * "hh"	Signed or unsigned char.@n
- * "h"	Signed or usigned short.@n
- * ""	Signed or usigned int (default value).@n
- * "l"	Signed or usigned long int.@n
- * "ll"	Signed or usigned long long int.@n
- * "z"	__native (non-standard extension).@n
- * 
- * 
- * CONVERSION:@n
- * %	Print percentile character itself.
- *
- * c	Print single character.
- *
- * s	Print zero terminated string. If a NULL value is passed as value, "(NULL)" is printed instead.
- * 
- * P, p	Print value of a pointer. Void * value is expected and it is printed in hexadecimal notation with prefix
- * 	(as with \%#X or \%#x for 32bit or \%#X / \%#x for 64bit long pointers).
- *
- * b	Print value as unsigned binary number. Prefix is not printed by default. (Nonstandard extension.)
- * 
- * o	Print value as unsigned octal number. Prefix is not printed by default. 
- *
- * d,i	Print signed decimal number. There is no difference between d and i conversion.
- *
- * u	Print unsigned decimal number.
- *
- * X, x	Print hexadecimal number with upper- or lower-case. Prefix is not printed by default.
- * 
- * All other characters from fmt except the formatting directives
- * are printed in verbatim.
- *
- * @param fmt Formatting NULL terminated string.
- * @return Number of printed characters or negative value on failure.
- */
-int printf(const char *fmt, ...)
-{
-	int irqpri;
-	int i = 0, j = 0; /* i is index of currently processed char from fmt, j is index to the first not printed nonformating character */
-	int end;
-	int counter; /* counter of printed characters */
-	int retval; /* used to store return values from called functions */
-	va_list ap;
-	char c;
-	qualifier_t qualifier;	/* type of argument */
-	int base;	/* base in which will be parameter (numbers only) printed */
-	__u64 number; /* argument value */
-	__native size; /* byte size of integer parameter */
-	int width, precision;
-	__u64 flags;
-	
-	counter = 0;
-	
-	va_start(ap, fmt);
-	
-	irqpri = interrupts_disable();
-	spinlock_lock(&printflock);
-
-	
-	while ((c = fmt[i])) {
-		/* control character */
-		if (c == '%' ) { 
-			/* print common characters if any processed */	
-			if (i > j) {
-				if ((retval = putnchars(&fmt[j], (__native)(i - j))) == EOF) { /* error */
-					counter = -counter;
-					goto out;
-				}
-				counter += retval;
-			}
-		
-			j = i;
-			/* parse modifiers */
-			flags = 0;
-			end = 0;
-			
-			do {
-				++i;
-				switch (c = fmt[i]) {
-					case '#': flags |= __PRINTF_FLAG_PREFIX; break;
-					case '-': flags |= __PRINTF_FLAG_LEFTALIGNED; break;
-					case '+': flags |= __PRINTF_FLAG_SHOWPLUS; break;
-					case ' ': flags |= __PRINTF_FLAG_SPACESIGN; break;
-					case '0': flags |= __PRINTF_FLAG_ZEROPADDED; break;
-					default: end = 1;
-				};	
-				
-			} while (end == 0);	
-			
-			/* width & '*' operator */
-			width = 0;
-			if (isdigit(fmt[i])) {
-				while (isdigit(fmt[i])) {
-					width *= 10;
-					width += fmt[i++] - '0';
-				}
-			} else if (fmt[i] == '*') {
-				/* get width value from argument list*/
-				i++;
-				width = (int)va_arg(ap, int);
-				if (width < 0) {
-					/* negative width means to set '-' flag */
-					width *= -1;
-					flags |= __PRINTF_FLAG_LEFTALIGNED;
-				}
-			}
-			
-			/* precision and '*' operator */	
-			precision = 0;
-			if (fmt[i] == '.') {
-				++i;
-				if (isdigit(fmt[i])) {
-					while (isdigit(fmt[i])) {
-						precision *= 10;
-						precision += fmt[i++] - '0';
-					}
-				} else if (fmt[i] == '*') {
-					/* get precision value from argument list*/
-					i++;
-					precision = (int)va_arg(ap, int);
-					if (precision < 0) {
-						/* negative precision means to ignore it */
-						precision = 0;
-					}
-				}
-			}
-
-			switch (fmt[i++]) {
-				/** TODO: unimplemented qualifiers:
-				 * t ptrdiff_t - ISO C 99
-				 */
-				case 'h':	/* char or short */
-					qualifier = PrintfQualifierShort;
-					if (fmt[i] == 'h') {
-						i++;
-						qualifier = PrintfQualifierByte;
-					}
-					break;
-				case 'l':	/* long or long long*/
-					qualifier = PrintfQualifierLong;
-					if (fmt[i] == 'l') {
-						i++;
-						qualifier = PrintfQualifierLongLong;
-					}
-					break;
-				case 'z':	/* __native */
-					qualifier = PrintfQualifierNative;
-					break;
-				default:
-					qualifier = PrintfQualifierInt; /* default type */
-					--i;
-			}	
-			
-			base = 10;
-
-			switch (c = fmt[i]) {
-
-				/*
-				* String and character conversions.
-				*/
-				case 's':
-					if ((retval = print_string(va_arg(ap, char*), width, precision, flags)) == EOF) {
-						counter = -counter;
-						goto out;
-					};
-					
-					counter += retval;
-					j = i + 1; 
-					goto next_char;
-				case 'c':
-					c = va_arg(ap, unsigned int);
-					if ((retval = print_char(c, width, flags )) == EOF) {
-						counter = -counter;
-						goto out;
-					};
-					
-					counter += retval;
-					j = i + 1;
-					goto next_char;
-
-				/* 
-				 * Integer values
-				*/
-				case 'P': /* pointer */
-				       	flags |= __PRINTF_FLAG_BIGCHARS;
-				case 'p':
-					flags |= __PRINTF_FLAG_PREFIX;
-					base = 16;
-					qualifier = PrintfQualifierPointer;
-					break;	
-				case 'b': 
-					base = 2;
-					break;
-				case 'o':
-					base = 8;
-					break;
-				case 'd':
-				case 'i':
-					flags |= __PRINTF_FLAG_SIGNED;  
-				case 'u':
-					break;
-				case 'X':
-					flags |= __PRINTF_FLAG_BIGCHARS;
-				case 'x':
-					base = 16;
-					break;
-				/* percentile itself */
-				case '%': 
-					j = i;
-					goto next_char;
-				/*
-				* Bad formatting.
-				*/
-				default:
-					/* Unknown format
-					 *  now, the j is index of '%' so we will
-					 * print whole bad format sequence
-					 */
-					goto next_char;		
-			}
-		
-		
-		/* Print integers */
-			/* print number */
-			switch (qualifier) {
-				case PrintfQualifierByte:
-					size = sizeof(unsigned char);
-					number = (__u64)va_arg(ap, unsigned int);
-					break;
-				case PrintfQualifierShort:
-					size = sizeof(unsigned short);
-					number = (__u64)va_arg(ap, unsigned int);
-					break;
-				case PrintfQualifierInt:
-					size = sizeof(unsigned int);
-					number = (__u64)va_arg(ap, unsigned int);
-					break;
-				case PrintfQualifierLong:
-					size = sizeof(unsigned long);
-					number = (__u64)va_arg(ap, unsigned long);
-					break;
-				case PrintfQualifierLongLong:
-					size = sizeof(unsigned long long);
-					number = (__u64)va_arg(ap, unsigned long long);
-					break;
-				case PrintfQualifierPointer:
-					size = sizeof(void *);
-					number = (__u64)(unsigned long)va_arg(ap, void *);
-					break;
-				case PrintfQualifierNative:
-					size = sizeof(__native);
-					number = (__u64)va_arg(ap, __native);
-					break;
-				default: /* Unknown qualifier */
-					counter = -counter;
-					goto out;
-					
-			}
-			
-			if (flags & __PRINTF_FLAG_SIGNED) {
-				if (number & (0x1 << (size*8 - 1))) {
-					flags |= __PRINTF_FLAG_NEGATIVE;
-				
-					if (size == sizeof(__u64)) {
-						number = -((__s64)number);
-					} else {
-						number = ~number;
-						number &= (~((0xFFFFFFFFFFFFFFFFll) <<  (size * 8)));
-						number++;
-					}
-				}
-			}
-
-			if ((retval = print_number(number, width, precision, base, flags)) == EOF ) {
-				counter = -counter;
-				goto out;
-			};
-
-			counter += retval;
-			j = i + 1;
-		}	
-next_char:
-			
-		++i;
-	}
-	
-	if (i > j) {
-		if ((retval = putnchars(&fmt[j], (__native)(i - j))) == EOF) { /* error */
-			counter = -counter;
-			goto out;
-		}
-		counter += retval;
-	}
-out:
-	spinlock_unlock(&printflock);
-	interrupts_restore(irqpri);
-	
-	va_end(ap);
-	return counter;
-}
Index: generic/src/debug/printf.c
===================================================================
--- generic/src/debug/printf.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
+++ generic/src/debug/printf.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <print.h>
+
+int printf(const char *fmt, ...)
+{
+	int ret;
+	va_list args;
+
+	va_start(args, fmt);
+
+	ret = vprintf(fmt, args);
+	
+	va_end(args);
+
+	return ret;
+}
+
Index: generic/src/debug/printf_core.c
===================================================================
--- generic/src/debug/printf_core.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
+++ generic/src/debug/printf_core.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
@@ -0,0 +1,723 @@
+/*
+ * Copyright (C) 2001-2004 Jakub Jermar
+ * Copyright (C) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file	print.c
+ * @brief	Printing functions.
+ */
+
+#include <printf/printf_core.h>
+#include <putchar.h>
+#include <print.h>
+#include <synch/spinlock.h>
+#include <arch/arg.h>
+#include <arch/asm.h>
+
+#include <arch.h>
+
+SPINLOCK_INITIALIZE(printflock);			/**< printf spinlock */
+
+#define __PRINTF_FLAG_PREFIX		0x00000001	/**< show prefixes 0x or 0*/
+#define __PRINTF_FLAG_SIGNED		0x00000002	/**< signed / unsigned number */
+#define __PRINTF_FLAG_ZEROPADDED	0x00000004	/**< print leading zeroes */
+#define __PRINTF_FLAG_LEFTALIGNED	0x00000010	/**< align to left */
+#define __PRINTF_FLAG_SHOWPLUS		0x00000020	/**< always show + sign */
+#define __PRINTF_FLAG_SPACESIGN		0x00000040	/**< print space instead of plus */
+#define __PRINTF_FLAG_BIGCHARS		0x00000080	/**< show big characters */
+#define __PRINTF_FLAG_NEGATIVE		0x00000100	/**< number has - sign */
+
+#define PRINT_NUMBER_BUFFER_SIZE	(64+5)		/**< Buffer big enought for 64 bit number
+							 * printed in base 2, sign, prefix and
+							 * 0 to terminate string.. (last one is only for better testing 
+							 * end of buffer by zero-filling subroutine)*/
+
+/** Enumeration of possible arguments types.
+ */
+typedef enum {
+	PrintfQualifierByte = 0,
+	PrintfQualifierShort,
+	PrintfQualifierInt,
+	PrintfQualifierLong,
+	PrintfQualifierLongLong,
+	PrintfQualifierNative,
+	PrintfQualifierPointer
+} qualifier_t;
+
+static char digits_small[] = "0123456789abcdef"; 	/**< Small hexadecimal characters */
+static char digits_big[] = "0123456789ABCDEF"; 	/**< Big hexadecimal characters */
+
+/** Checks c for a digit.
+ * @param c One character.
+ * @return nonzero if c is from interval '0 to '9'.
+ */
+static inline int isdigit(int c)
+{
+	return ((c >= '0' )&&( c <= '9'));
+}
+
+/** Compute length of given zero terminated string.
+ * @param str Pointer to valid string.
+ * @return string length without trailing zero.
+ */
+static __native strlen(const char *str) 
+{
+	__native counter = 0;
+
+	while (str[counter] != 0) {
+		counter++;
+	}
+
+	return counter;
+}
+
+/** Print count chars from buffer without adding newline
+ * @param buf Buffer with size at least count bytes - NULL pointer NOT allowed!
+ * @param count 
+ * @param ps output method and its data
+ * @return 0 on success, EOF on fail
+ */
+static int printf_putnchars(const char * buf, size_t count, struct printf_spec *ps)
+{
+	if (ps->write((void *)buf, count, ps->data) == count) {
+		return 0;
+	}
+	
+	return EOF;
+}
+
+/** Print string without added newline
+ * @param str string to print
+ * @param ps write function specification and support data
+ * @return 0 on success or EOF on fail
+ */
+static int printf_putstr(const char * str, struct printf_spec *ps)
+{
+	size_t count;
+	
+	if (str == NULL) {
+		return printf_putnchars("(NULL)", 6, ps);
+	}
+
+	count = strlen(str);
+
+	if (ps->write((void *) str, count, ps->data) == count) {
+		return 0;
+	}
+	
+	return EOF;
+}
+
+/** Print one character to output
+ * @param c one character
+ * @param ps output method
+ * @return printed character or EOF
+ */
+static int printf_putchar(int c, struct printf_spec *ps)
+{
+	unsigned char ch = c;
+	
+	if (ps->write((void *) &ch, 1, ps->data) == 1) {
+		return c;
+	}
+	
+	return EOF;
+}
+
+/** Print one formatted character
+ * @param c character to print
+ * @param width 
+ * @param flags
+ * @return number of printed characters or EOF
+ */
+static int print_char(char c, int width, __u64 flags, struct printf_spec *ps)
+{
+	int counter = 0;
+	
+	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
+		while (--width > 0) { 	/* one space is consumed by character itself hence predecrement */
+			/* FIXME: painful slow */
+			printf_putchar(' ', ps);	
+			++counter;
+		}
+	}
+	
+ 	if (printf_putchar(c, ps) == EOF) {
+		return EOF;
+	}
+
+	while (--width > 0) { /* one space is consumed by character itself hence predecrement */
+		printf_putchar(' ', ps);
+		++counter;
+	}
+	
+	return ++counter;
+}
+
+/** Print one string
+ * @param s string
+ * @param width 
+ * @param precision
+ * @param flags
+ * @return number of printed characters or EOF
+ */
+						
+static int print_string(char *s, int width, int precision, __u64 flags, struct printf_spec *ps)
+{
+	int counter = 0;
+	size_t size;
+
+	if (s == NULL) {
+		return printf_putstr("(NULL)", ps);
+	}
+	
+	size = strlen(s);
+
+	/* print leading spaces */
+
+	if (precision == 0) 
+		precision = size;
+
+	width -= precision;
+	
+	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
+		while (width-- > 0) { 	
+			printf_putchar(' ', ps);	
+			counter++;
+		}
+	}
+
+	while (precision > size) {
+		precision--;
+		printf_putchar(' ', ps);	
+		++counter;
+	}
+	
+ 	if (printf_putnchars(s, precision, ps) == EOF) {
+		return EOF;
+	}
+
+	counter += precision;
+
+	while (width-- > 0) {
+		printf_putchar(' ', ps);	
+		++counter;
+	}
+	
+	return ++counter;
+}
+
+
+/** Print number in given base
+ *
+ * Print significant digits of a number in given
+ * base.
+ *
+ * @param num  Number to print.
+ * @param width
+ * @param precision
+ * @param base Base to print the number in (should
+ *             be in range 2 .. 16).
+ * @param flags output modifiers
+ * @return number of written characters or EOF
+ *
+ */
+static int print_number(__u64 num, int width, int precision, int base , __u64 flags, struct printf_spec *ps)
+{
+	char *digits = digits_small;
+	char d[PRINT_NUMBER_BUFFER_SIZE];	/* this is good enough even for base == 2, prefix and sign */
+	char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1];
+	int size = 0; /* size of number with all prefixes and signs */
+	int number_size; /* size of plain number */
+	int written = 0;
+	char sgn;
+	
+	if (flags & __PRINTF_FLAG_BIGCHARS) 
+		digits = digits_big;	
+	
+	*ptr-- = 0; /* Put zero at end of string */
+
+	if (num == 0) {
+		*ptr-- = '0';
+		size++;
+	} else {
+		do {
+			*ptr-- = digits[num % base];
+			size++;
+		} while (num /= base);
+	}
+	
+	number_size = size;
+
+	/* Collect sum of all prefixes/signs/... to calculate padding and leading zeroes */
+	if (flags & __PRINTF_FLAG_PREFIX) {
+		switch(base) {
+			case 2:	/* Binary formating is not standard, but usefull */
+				size += 2;
+				break;
+			case 8:
+				size++;
+				break;
+			case 16:
+				size += 2;
+				break;
+		}
+	}
+
+	sgn = 0;
+	if (flags & __PRINTF_FLAG_SIGNED) {
+		if (flags & __PRINTF_FLAG_NEGATIVE) {
+			sgn = '-';
+			size++;
+		} else if (flags & __PRINTF_FLAG_SHOWPLUS) {
+				sgn = '+';
+				size++;
+			} else if (flags & __PRINTF_FLAG_SPACESIGN) {
+					sgn = ' ';
+					size++;
+				}
+	}
+
+	if (flags & __PRINTF_FLAG_LEFTALIGNED) {
+		flags &= ~__PRINTF_FLAG_ZEROPADDED;
+	}
+
+	/* if number is leftaligned or precision is specified then zeropadding is ignored */
+	if (flags & __PRINTF_FLAG_ZEROPADDED) {
+		if ((precision == 0) && (width > size)) {
+			precision = width - size + number_size;
+		}
+	}
+
+	/* print leading spaces */
+	if (number_size > precision) /* We must print whole number not only a part */
+		precision = number_size;
+
+	width -= precision + size - number_size;
+	
+	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
+		while (width-- > 0) { 	
+			printf_putchar(' ', ps);	
+			written++;
+		}
+	}
+	
+	/* print sign */
+	if (sgn) {
+		printf_putchar(sgn, ps);
+		written++;
+	}
+	
+	/* print prefix */
+	
+	if (flags & __PRINTF_FLAG_PREFIX) {
+		switch(base) {
+			case 2:	/* Binary formating is not standard, but usefull */
+				printf_putchar('0', ps);
+				if (flags & __PRINTF_FLAG_BIGCHARS) {
+					printf_putchar('B', ps);
+				} else {
+					printf_putchar('b', ps);
+				}
+				written += 2;
+				break;
+			case 8:
+				printf_putchar('o', ps);
+				written++;
+				break;
+			case 16:
+				printf_putchar('0', ps);
+				if (flags & __PRINTF_FLAG_BIGCHARS) {
+					printf_putchar('X', ps);
+				} else {
+					printf_putchar('x', ps);
+				}
+				written += 2;
+				break;
+		}
+	}
+
+	/* print leading zeroes */
+	precision -= number_size;
+	while (precision-- > 0) { 	
+		printf_putchar('0', ps);	
+		written++;
+	}
+
+	
+	/* print number itself */
+
+	written += printf_putstr(++ptr, ps);
+	
+	/* print ending spaces */
+	
+	while (width-- > 0) { 	
+		printf_putchar(' ', ps);	
+		written++;
+	}
+
+	return written;
+}
+
+
+/** Print formatted string.
+ *
+ * Print string formatted according to the fmt parameter
+ * and variadic arguments. Each formatting directive
+ * must have the following form:
+ * 
+ * 	\% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION
+ *
+ * FLAGS:@n
+ * 	- "#" Force to print prefix.
+ * 	For conversion \%o the prefix is 0, for %x and \%X prefixes are 0x and 0X
+ *	and for conversion \%b the prefix is 0b.
+ *
+ * 	- "-"	Align to left.
+ *
+ * 	- "+"	Print positive sign just as negative.
+ *
+ * 	- " "	If the printed number is positive and "+" flag is not set, print space in
+ *	place of sign.
+ *
+ * 	- "0"	Print 0 as padding instead of spaces. Zeroes are placed between sign and the
+ *	rest of the number. This flag is ignored if "-" flag is specified.
+ * 
+ * WIDTH:@n
+ * 	- Specify minimal width of printed argument. If it is bigger, width is ignored.
+ * If width is specified with a "*" character instead of number, width is taken from
+ * parameter list. And integer parameter is expected before parameter for processed
+ * conversion specification. If this value is negative its absolute value is taken
+ * and the "-" flag is set.
+ *
+ * PRECISION:@n
+ * 	- Value precision. For numbers it specifies minimum valid numbers.
+ * Smaller numbers are printed with leading zeroes. Bigger numbers are not affected.
+ * Strings with more than precision characters are cut off.
+ * Just as with width, an "*" can be used used instead of a number.
+ * An integer value is then expected in parameters. When both width and precision
+ * are specified using "*", the first parameter is used for width and the second one
+ * for precision.
+ * 
+ * TYPE:@n
+ * 	- "hh"	Signed or unsigned char.@n
+ * 	- "h"	Signed or usigned short.@n
+ * 	- ""	Signed or usigned int (default value).@n
+ * 	- "l"	Signed or usigned long int.@n
+ * 	- "ll"	Signed or usigned long long int.@n
+ * 	- "z"	__native (non-standard extension).@n
+ * 
+ * 
+ * CONVERSION:@n
+ * 	- %	Print percentile character itself.
+ *
+ * 	- c	Print single character.
+ *
+ * 	- s	Print zero terminated string. If a NULL value is passed as value, "(NULL)" is printed instead.
+ * 
+ * 	- P, p	Print value of a pointer. Void * value is expected and it is printed in hexadecimal notation with prefix
+ * 	(as with \%#X or \%#x for 32bit or \%#X / \%#x for 64bit long pointers).
+ *
+ * 	- b	Print value as unsigned binary number. Prefix is not printed by default. (Nonstandard extension.)
+ * 
+ * 	- o	Print value as unsigned octal number. Prefix is not printed by default. 
+ *
+ * 	- d,i	Print signed decimal number. There is no difference between d and i conversion.
+ *
+ * 	- u	Print unsigned decimal number.
+ *
+ * 	- X, x	Print hexadecimal number with upper- or lower-case. Prefix is not printed by default.
+ * 
+ * All other characters from fmt except the formatting directives
+ * are printed in verbatim.
+ *
+ * @param fmt Formatting NULL terminated string.
+ * @return Number of printed characters or negative value on failure.
+ */
+int printf_core(const char *fmt, struct printf_spec *ps, va_list ap)
+{
+	int irqpri;
+	int i = 0, j = 0; /* i is index of currently processed char from fmt, j is index to the first not printed nonformating character */
+	int end;
+	int counter; /* counter of printed characters */
+	int retval; /* used to store return values from called functions */
+	char c;
+	qualifier_t qualifier;	/* type of argument */
+	int base;	/* base in which will be parameter (numbers only) printed */
+	__u64 number; /* argument value */
+	size_t	size; /* byte size of integer parameter */
+	int width, precision;
+	__u64 flags;
+	
+	counter = 0;
+	
+	irqpri = interrupts_disable();
+	spinlock_lock(&printflock);
+
+	while ((c = fmt[i])) {
+		/* control character */
+		if (c == '%' ) { 
+			/* print common characters if any processed */	
+			if (i > j) {
+				if ((retval = printf_putnchars(&fmt[j], (size_t)(i - j), ps)) == EOF) { /* error */
+					counter = -counter;
+					goto out;
+				}
+				counter += retval;
+			}
+		
+			j = i;
+			/* parse modifiers */
+			flags = 0;
+			end = 0;
+			
+			do {
+				++i;
+				switch (c = fmt[i]) {
+					case '#': flags |= __PRINTF_FLAG_PREFIX; break;
+					case '-': flags |= __PRINTF_FLAG_LEFTALIGNED; break;
+					case '+': flags |= __PRINTF_FLAG_SHOWPLUS; break;
+					case ' ': flags |= __PRINTF_FLAG_SPACESIGN; break;
+					case '0': flags |= __PRINTF_FLAG_ZEROPADDED; break;
+					default: end = 1;
+				};	
+				
+			} while (end == 0);	
+			
+			/* width & '*' operator */
+			width = 0;
+			if (isdigit(fmt[i])) {
+				while (isdigit(fmt[i])) {
+					width *= 10;
+					width += fmt[i++] - '0';
+				}
+			} else if (fmt[i] == '*') {
+				/* get width value from argument list*/
+				i++;
+				width = (int)va_arg(ap, int);
+				if (width < 0) {
+					/* negative width means to set '-' flag */
+					width *= -1;
+					flags |= __PRINTF_FLAG_LEFTALIGNED;
+				}
+			}
+			
+			/* precision and '*' operator */	
+			precision = 0;
+			if (fmt[i] == '.') {
+				++i;
+				if (isdigit(fmt[i])) {
+					while (isdigit(fmt[i])) {
+						precision *= 10;
+						precision += fmt[i++] - '0';
+					}
+				} else if (fmt[i] == '*') {
+					/* get precision value from argument list*/
+					i++;
+					precision = (int)va_arg(ap, int);
+					if (precision < 0) {
+						/* negative precision means to ignore it */
+						precision = 0;
+					}
+				}
+			}
+
+			switch (fmt[i++]) {
+				/** TODO: unimplemented qualifiers:
+				 * t ptrdiff_t - ISO C 99
+				 */
+				case 'h':	/* char or short */
+					qualifier = PrintfQualifierShort;
+					if (fmt[i] == 'h') {
+						i++;
+						qualifier = PrintfQualifierByte;
+					}
+					break;
+				case 'l':	/* long or long long*/
+					qualifier = PrintfQualifierLong;
+					if (fmt[i] == 'l') {
+						i++;
+						qualifier = PrintfQualifierLongLong;
+					}
+					break;
+				case 'z':	/* __native */
+					qualifier = PrintfQualifierNative;
+					break;
+				default:
+					qualifier = PrintfQualifierInt; /* default type */
+					--i;
+			}	
+			
+			base = 10;
+
+			switch (c = fmt[i]) {
+
+				/*
+				* String and character conversions.
+				*/
+				case 's':
+					if ((retval = print_string(va_arg(ap, char*), width, precision, flags, ps)) == EOF) {
+						counter = -counter;
+						goto out;
+					};
+					
+					counter += retval;
+					j = i + 1; 
+					goto next_char;
+				case 'c':
+					c = va_arg(ap, unsigned int);
+					if ((retval = print_char(c, width, flags, ps)) == EOF) {
+						counter = -counter;
+						goto out;
+					};
+					
+					counter += retval;
+					j = i + 1;
+					goto next_char;
+
+				/* 
+				 * Integer values
+				*/
+				case 'P': /* pointer */
+				       	flags |= __PRINTF_FLAG_BIGCHARS;
+				case 'p':
+					flags |= __PRINTF_FLAG_PREFIX;
+					base = 16;
+					qualifier = PrintfQualifierPointer;
+					break;	
+				case 'b': 
+					base = 2;
+					break;
+				case 'o':
+					base = 8;
+					break;
+				case 'd':
+				case 'i':
+					flags |= __PRINTF_FLAG_SIGNED;  
+				case 'u':
+					break;
+				case 'X':
+					flags |= __PRINTF_FLAG_BIGCHARS;
+				case 'x':
+					base = 16;
+					break;
+				/* percentile itself */
+				case '%': 
+					j = i;
+					goto next_char;
+				/*
+				* Bad formatting.
+				*/
+				default:
+					/* Unknown format
+					 *  now, the j is index of '%' so we will
+					 * print whole bad format sequence
+					 */
+					goto next_char;		
+			}
+		
+		
+		/* Print integers */
+			/* print number */
+			switch (qualifier) {
+				case PrintfQualifierByte:
+					size = sizeof(unsigned char);
+					number = (__u64)va_arg(ap, unsigned int);
+					break;
+				case PrintfQualifierShort:
+					size = sizeof(unsigned short);
+					number = (__u64)va_arg(ap, unsigned int);
+					break;
+				case PrintfQualifierInt:
+					size = sizeof(unsigned int);
+					number = (__u64)va_arg(ap, unsigned int);
+					break;
+				case PrintfQualifierLong:
+					size = sizeof(unsigned long);
+					number = (__u64)va_arg(ap, unsigned long);
+					break;
+				case PrintfQualifierLongLong:
+					size = sizeof(unsigned long long);
+					number = (__u64)va_arg(ap, unsigned long long);
+					break;
+				case PrintfQualifierPointer:
+					size = sizeof(void *);
+					number = (__u64)(unsigned long)va_arg(ap, void *);
+					break;
+				case PrintfQualifierNative:
+					size = sizeof(__native);
+					number = (__u64)va_arg(ap, __native);
+					break;
+				default: /* Unknown qualifier */
+					counter = -counter;
+					goto out;
+			}
+			
+			if (flags & __PRINTF_FLAG_SIGNED) {
+				if (number & (0x1 << (size*8 - 1))) {
+					flags |= __PRINTF_FLAG_NEGATIVE;
+				
+					if (size == sizeof(__u64)) {
+						number = -((__s64)number);
+					} else {
+						number = ~number;
+						number &= (~((0xFFFFFFFFFFFFFFFFll) <<  (size * 8)));
+						number++;
+					}
+				}
+			}
+
+			if ((retval = print_number(number, width, precision, base, flags, ps)) == EOF ) {
+				counter = -counter;
+				goto out;
+			};
+
+			counter += retval;
+			j = i + 1;
+		}	
+next_char:
+			
+		++i;
+	}
+	
+	if (i > j) {
+		if ((retval = printf_putnchars(&fmt[j], (__native)(i - j), ps)) == EOF) { /* error */
+			counter = -counter;
+			goto out;
+			
+		}
+		counter += retval;
+	}
+
+out:
+	spinlock_unlock(&printflock);
+	interrupts_restore(irqpri);
+	
+	return counter;
+}
+
Index: generic/src/debug/snprintf.c
===================================================================
--- generic/src/debug/snprintf.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
+++ generic/src/debug/snprintf.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <print.h>
+#include <printf/printf_core.h>
+
+int snprintf(char *str, size_t size, const char *fmt, ...)
+{
+	int ret;
+	va_list args;
+	
+	va_start(args, fmt);
+	ret = vsnprintf(str, size, fmt, args);
+
+	va_end(args);
+
+	return ret;
+}
Index: generic/src/debug/sprintf.c
===================================================================
--- generic/src/debug/sprintf.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
+++ generic/src/debug/sprintf.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <print.h>
+
+int sprintf(char *str, const char *fmt, ...)
+{
+	int ret;
+	va_list args;
+	
+	va_start(args, fmt);
+	ret = vsprintf(str, fmt, args);
+
+	va_end(args);
+
+	return ret;
+}
Index: generic/src/debug/vprintf.c
===================================================================
--- generic/src/debug/vprintf.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
+++ generic/src/debug/vprintf.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <print.h>
+#include <printf/printf_core.h>
+#include <putchar.h>
+
+int vprintf_write(const char *str, size_t count, void *unused);
+
+int vprintf_write(const char *str, size_t count, void *unused)
+{
+	size_t i = 0;
+	for (; i < count; i++)
+		putchar(str[i]);
+	return i;
+}
+
+int vprintf(const char *fmt, va_list ap)
+{
+	struct printf_spec ps = {(int(*)(void *, size_t, void *))vprintf_write, NULL};
+	return printf_core(fmt, &ps, ap);
+
+}
+
+
Index: generic/src/debug/vsnprintf.c
===================================================================
--- generic/src/debug/vsnprintf.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
+++ generic/src/debug/vsnprintf.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <print.h>
+#include <printf/printf_core.h>
+#include <memstr.h>
+
+struct vsnprintf_data {
+	size_t size; /* total space for string */
+	size_t len; /* count of currently used characters */
+	char *string; /* destination string */
+};
+
+int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data);
+
+/** Write string to given buffer.
+ * Write at most data->size characters including trailing zero. According to C99 has snprintf to return number
+ * of characters that would have been written if enough space had been available. Hence the return value is not
+ * number of really printed characters but size of input string. Number of really used characters 
+ * is stored in data->len.
+ * @param str source string to print
+ * @param count size of source string
+ * @param data structure with destination string, counter of used space and total string size.
+ * @return number of characters to print (not characters really printed!)
+ */
+int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data)
+{
+	size_t i,j;
+	i = data->size - data->len;
+	j = count;
+
+	if (i > 0) {
+		if (i <= j) { 
+			if (i == 1) {
+				/* We have only one free byte left in buffer => write there trailing zero */
+				data->string[data->size - 1] = 0;
+				data->len = data->size;
+			} else {
+				/* We have not enought space for whole string with the trailing zero => print only a part of string */
+				memcpy((void *)(data->string + data->len), (void *)str, i - 1);
+				data->string[data->size - 1] = 0;
+				data->len = data->size;
+			}
+		} else {
+			/* Buffer is big enought to print whole string */
+			memcpy((void *)(data->string + data->len), (void *)str, j);
+			data->len += j;
+			/* Put trailing zero at end, but not count it into data->len so it could be rewritten next time */
+			data->string[data->len] = 0;
+		}
+	}
+	
+	return count;	
+}
+
+int vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
+{
+	struct vsnprintf_data data = {size, 0, str};
+	struct printf_spec ps = {(int(*)(void *, size_t, void *))vsnprintf_write, &data};
+
+	/* Print 0 at end of string - fix the case that nothing will be printed */
+	if (size > 0)
+		str[0] = 0;
+	
+	/* vsnprintf_write ensures that str will be terminated by zero. */
+	return printf_core(fmt, &ps, ap);
+}
+
+
Index: generic/src/debug/vsprintf.c
===================================================================
--- generic/src/debug/vsprintf.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
+++ generic/src/debug/vsprintf.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <print.h>
+
+int vsprintf(char *str, const char *fmt, va_list ap)
+{
+	return vsnprintf(str, (size_t)-1, fmt, ap);
+}
+
Index: test/print/print1/test.c
===================================================================
--- test/print/print1/test.c	(revision 7dd1787643001828803b90e39bfe964bead011fa)
+++ test/print/print1/test.c	(revision e499a30a2407f3ac9931d745e5f8b44583979b6a)
@@ -29,7 +29,12 @@
 #include <test.h>
 
+#define BUFFER_SIZE 32
+
 void test(void)
 {
 	__native nat = 0x12345678u;
+	
+	unsigned char buffer[BUFFER_SIZE];
+	
 	printf(" Printf test \n");
 	
@@ -47,4 +52,13 @@
 	
 	printf(" Print to NULL '%s'\n",NULL);
+
+	printf("Print short text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
+	snprintf(buffer, BUFFER_SIZE, "Short %s", "text");
+	printf("Result is: '%s'\n", buffer);
+	
+	printf("Print long text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
+	snprintf(buffer, BUFFER_SIZE, "Very long %s. This text`s length is more than %d. We are interested in the result.", "text" , BUFFER_SIZE);
+	printf("Result is: '%s'\n", buffer);
+	
 	return;
 }
