Index: kernel/generic/include/console/chardev.h
===================================================================
--- kernel/generic/include/console/chardev.h	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/include/console/chardev.h	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -72,5 +72,5 @@
 typedef struct {
 	/** Write character to output. */
-	void (* write)(struct outdev *, char c, bool silent);
+	void (* write)(struct outdev *, wchar_t c, bool silent);
 } outdev_operations_t;
 
Index: kernel/generic/include/console/console.h
===================================================================
--- kernel/generic/include/console/console.h	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/include/console/console.h	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -53,5 +53,4 @@
 extern uint8_t _getc(indev_t *indev);
 extern count_t gets(indev_t *indev, char *buf, size_t buflen);
-extern void putchar(char c);
 extern unative_t sys_klog(int fd, const void * buf, size_t count);
 
Index: kernel/generic/include/print.h
===================================================================
--- kernel/generic/include/print.h	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/include/print.h	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -47,9 +47,7 @@
 extern int puts(const char *s);
 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);
 
Index: kernel/generic/include/printf/printf_core.h
===================================================================
--- kernel/generic/include/printf/printf_core.h	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/include/printf/printf_core.h	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -36,17 +36,20 @@
 #define KERN_PRINTF_CORE_H_
 
-#include <arch/types.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,... */
+typedef struct {
+	/* UTF-8 output function, returns number of printed UTF-8 characters or EOF */
+	int (*write_utf8)(const char *, size_t, void *);
+	
+	/* UTF-32 output function, returns number of printed UTF-32 characters or EOF */
+	int (*write_utf32)(const wchar_t *, size_t, void *);
+	
+	/* User data - output stream specification, state, locks, etc. */
 	void *data;
+} printf_spec_t;
 
-};
-
-int printf_core(const char *fmt, struct printf_spec *ps, va_list ap);
+int printf_core(const char *fmt, printf_spec_t *ps, va_list ap);
 
 #endif
Index: kernel/generic/include/putchar.h
===================================================================
--- kernel/generic/include/putchar.h	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/include/putchar.h	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -36,5 +36,5 @@
 #define KERN_PUTCHAR_H_
 
-extern void putchar(const char ch);
+extern void putchar(const wchar_t ch);
 
 #endif
Index: kernel/generic/src/console/chardev.c
===================================================================
--- kernel/generic/src/console/chardev.c	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/src/console/chardev.c	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -34,5 +34,4 @@
 
 #include <console/chardev.h>
-#include <putchar.h>
 #include <synch/waitq.h>
 #include <synch/spinlock.h>
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/src/console/console.c	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -47,13 +47,14 @@
 #include <func.h>
 #include <print.h>
+#include <putchar.h>
 #include <atomic.h>
 #include <syscall/copy.h>
 #include <errno.h>
 
-#define KLOG_SIZE PAGE_SIZE
-#define KLOG_LATENCY 8
+#define KLOG_SIZE     PAGE_SIZE
+#define KLOG_LATENCY  8
 
 /** Kernel log cyclic buffer */
-static char klog[KLOG_SIZE] __attribute__ ((aligned (PAGE_SIZE)));
+static wchar_t klog[KLOG_SIZE] __attribute__ ((aligned (PAGE_SIZE)));
 
 /** Kernel log initialized */
@@ -96,9 +97,9 @@
 	
 	klog_parea.pbase = (uintptr_t) faddr;
-	klog_parea.frames = SIZE2FRAMES(KLOG_SIZE);
+	klog_parea.frames = SIZE2FRAMES(sizeof(klog));
 	ddi_parea_register(&klog_parea);
 	
 	sysinfo_set_item_val("klog.faddr", NULL, (unative_t) faddr);
-	sysinfo_set_item_val("klog.pages", NULL, SIZE2FRAMES(KLOG_SIZE));
+	sysinfo_set_item_val("klog.pages", NULL, SIZE2FRAMES(sizeof(klog)));
 	
 	spinlock_lock(&klog_lock);
@@ -246,5 +247,5 @@
 }
 
-void putchar(char c)
+void putchar(const wchar_t ch)
 {
 	spinlock_lock(&klog_lock);
@@ -259,5 +260,5 @@
 	
 	/* Store character in the cyclic kernel log */
-	klog[(klog_start + klog_len) % KLOG_SIZE] = c;
+	klog[(klog_start + klog_len) % KLOG_SIZE] = ch;
 	if (klog_len < KLOG_SIZE)
 		klog_len++;
@@ -266,5 +267,5 @@
 	
 	if ((stdout) && (stdout->op->write))
-		stdout->op->write(stdout, c, silent);
+		stdout->op->write(stdout, ch, silent);
 	else {
 		/* The character is just in the kernel log */
@@ -279,5 +280,5 @@
 	/* Check notify uspace to update */
 	bool update;
-	if ((klog_uspace > KLOG_LATENCY) || (c == '\n'))
+	if ((klog_uspace > KLOG_LATENCY) || (ch == '\n'))
 		update = true;
 	else
@@ -295,9 +296,9 @@
  *
  */
-unative_t sys_klog(int fd, const void * buf, size_t count) 
+unative_t sys_klog(int fd, const void * buf, size_t count)
 {
 	char *data;
 	int rc;
-
+	
 	if (count > PAGE_SIZE)
 		return ELIMIT;
Index: kernel/generic/src/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/src/console/kconsole.c	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -56,4 +56,5 @@
 #include <symtab.h>
 #include <errno.h>
+#include <putchar.h>
 
 /** Simple kernel console.
@@ -160,7 +161,7 @@
 
 /** Print count times a character */
-static void rdln_print_c(char ch, int count)
-{
-	int i;
+static void rdln_print_c(wchar_t ch, count_t count)
+{
+	count_t i;
 	for (i = 0; i < count; i++)
 		putchar(ch);
Index: kernel/generic/src/printf/printf.c
===================================================================
--- kernel/generic/src/printf/printf.c	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/src/printf/printf.c	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -34,5 +34,4 @@
 
 #include <print.h>
-int printf(const char *fmt, ...);
 
 int printf(const char *fmt, ...)
@@ -40,11 +39,11 @@
 	int ret;
 	va_list args;
-
+	
 	va_start(args, fmt);
-
+	
 	ret = vprintf(fmt, args);
 	
 	va_end(args);
-
+	
 	return ret;
 }
Index: kernel/generic/src/printf/printf_core.c
===================================================================
--- kernel/generic/src/printf/printf_core.c	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/src/printf/printf_core.c	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -2,4 +2,5 @@
  * Copyright (c) 2001-2004 Jakub Jermar
  * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2009 Martin Decky
  * All rights reserved.
  *
@@ -28,14 +29,13 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
 /**
  * @file
- * @brief	Printing functions.
+ * @brief Printing functions.
  */
 
 #include <printf/printf_core.h>
-#include <putchar.h>
 #include <print.h>
 #include <arch/arg.h>
@@ -45,19 +45,19 @@
 
 /** show prefixes 0x or 0 */
-#define __PRINTF_FLAG_PREFIX		0x00000001
+#define __PRINTF_FLAG_PREFIX       0x00000001
 /** signed / unsigned number */
-#define __PRINTF_FLAG_SIGNED		0x00000002
+#define __PRINTF_FLAG_SIGNED       0x00000002
 /** print leading zeroes */
-#define __PRINTF_FLAG_ZEROPADDED	0x00000004
+#define __PRINTF_FLAG_ZEROPADDED   0x00000004
 /** align to left */
-#define __PRINTF_FLAG_LEFTALIGNED	0x00000010
+#define __PRINTF_FLAG_LEFTALIGNED  0x00000010
 /** always show + sign */
-#define __PRINTF_FLAG_SHOWPLUS		0x00000020
+#define __PRINTF_FLAG_SHOWPLUS     0x00000020
 /** print space instead of plus */
-#define __PRINTF_FLAG_SPACESIGN		0x00000040
+#define __PRINTF_FLAG_SPACESIGN    0x00000040
 /** show big characters */
-#define __PRINTF_FLAG_BIGCHARS		0x00000080
+#define __PRINTF_FLAG_BIGCHARS     0x00000080
 /** number has - sign */
-#define __PRINTF_FLAG_NEGATIVE		0x00000100
+#define __PRINTF_FLAG_NEGATIVE     0x00000100
 
 /**
@@ -66,5 +66,5 @@
  * zero-filling subroutine)
  */
-#define PRINT_NUMBER_BUFFER_SIZE	(64 + 5)	
+#define PRINT_NUMBER_BUFFER_SIZE  (64 + 5)
 
 /** Enumeration of possible arguments types.
@@ -79,67 +79,100 @@
 } qualifier_t;
 
+static char nullstr[] = "(NULL)";
 static char digits_small[] = "0123456789abcdef";
 static char digits_big[] = "0123456789ABCDEF";
 
-/** Print one or more characters without adding newline.
- *
- * @param buf		Buffer with size at least count bytes. NULL pointer is
- *			not allowed!
- * @param count		Number of characters to print.
- * @param ps		Output method and its data.
- * @return		Number of characters printed.
- */
-static int printf_putnchars(const char * buf, size_t count,
-    struct printf_spec *ps)
-{
-	return ps->write((void *) buf, count, ps->data);
-}
-
-/** Print a string without adding a newline.
- *
- * @param str		String to print.
- * @param ps		Write function specification and support data.
- * @return		Number of characters printed.
- */
-static int printf_putstr(const char * str, struct printf_spec *ps)
-{
-	size_t count;
-	
-	if (str == NULL) {
-		char *nullstr = "(NULL)";
-		return printf_putnchars(nullstr, strlen(nullstr), ps);
-	}
-
-	count = strlen(str);
-
-	return ps->write((void *) str, count, ps->data);
-}
-
-/** Print one character.
- *
- * @param c		Character to be printed.
- * @param ps		Output method.
- *
- * @return		Number of characters printed.
- */
-static int printf_putchar(int c, struct printf_spec *ps)
-{
-	unsigned char ch = c;
-	
-	return ps->write((void *) &ch, 1, ps->data);
-}
-
-/** Print one formatted character.
- *
- * @param c		Character to print.
- * @param width		Width modifier.
- * @param flags		Flags that change the way the character is printed.
- *
- * @return		Number of characters printed, negative value on failure.
- */
-static int print_char(char c, int width, uint64_t flags, struct printf_spec *ps)
-{
-	int counter = 0;
-	
+/** Print one or more UTF-8 characters without adding newline.
+ *
+ * @param buf  Buffer holding UTF-8 characters with size of
+ *             at least size bytes. NULL is not allowed!
+ * @param size Size of the buffer in bytes.
+ * @param ps   Output method and its data.
+ *
+ * @return Number of UTF-8 characters printed.
+ *
+ */
+static int printf_putnchars_utf8(const char *buf, size_t size,
+    printf_spec_t *ps)
+{
+	return ps->write_utf8((void *) buf, size, ps->data);
+}
+
+/** Print one or more UTF-32 characters without adding newline.
+ *
+ * @param buf  Buffer holding UTF-32 characters with size of
+ *             at least size bytes. NULL is not allowed!
+ * @param size Size of the buffer in bytes.
+ * @param ps   Output method and its data.
+ *
+ * @return Number of UTF-32 characters printed.
+ *
+ */
+static int printf_putnchars_utf32(const wchar_t *buf, size_t size,
+    printf_spec_t *ps)
+{
+	return ps->write_utf32((void *) buf, size, ps->data);
+}
+
+/** Print UTF-8 string without adding a newline.
+ *
+ * @param str UTF-8 string to print.
+ * @param ps  Write function specification and support data.
+ *
+ * @return Number of UTF-8 characters printed.
+ *
+ */
+static int printf_putstr(const char *str, printf_spec_t *ps)
+{
+	if (str == NULL)
+		return printf_putnchars_utf8(nullstr, strlen(nullstr), ps);
+	
+	return ps->write_utf8((void *) str, strlen(str), ps->data);
+}
+
+/** Print one ASCII character.
+ *
+ * @param c  ASCII character to be printed.
+ * @param ps Output method.
+ *
+ * @return Number of characters printed.
+ *
+ */
+static int printf_putchar(const char ch, printf_spec_t *ps)
+{
+	if (!ascii_check(ch))
+		return ps->write_utf8((void *) &invalch, 1, ps->data);
+	
+	return ps->write_utf8(&ch, 1, ps->data);
+}
+
+/** Print one UTF-32 character.
+ *
+ * @param c  UTF-32 character to be printed.
+ * @param ps Output method.
+ *
+ * @return Number of characters printed.
+ *
+ */
+static int printf_putwchar(const wchar_t ch, printf_spec_t *ps)
+{
+	if (!unicode_check(ch))
+		return ps->write_utf8((void *) &invalch, 1, ps->data);
+	
+	return ps->write_utf32(&ch, 1, ps->data);
+}
+
+/** Print one formatted ASCII character.
+ *
+ * @param ch    Character to print.
+ * @param width Width modifier.
+ * @param flags Flags that change the way the character is printed.
+ *
+ * @return Number of characters printed, negative value on failure.
+ *
+ */
+static int print_char(const char ch, int width, uint32_t flags, printf_spec_t *ps)
+{
+	count_t counter = 0;
 	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
 		while (--width > 0) {
@@ -148,73 +181,149 @@
 			 * the predecrement.
 			 */
-			if (printf_putchar(' ', ps) > 0)	
-				++counter;
-		}
-	}
-	
- 	if (printf_putchar(c, ps) > 0)
+			if (printf_putchar(' ', ps) > 0)
+				counter++;
+		}
+	}
+	
+	if (printf_putchar(ch, ps) > 0)
 		counter++;
-
+	
 	while (--width > 0) {
+		/*
+		 * One space is consumed by the character itself, hence
+		 * the predecrement.
+		 */
+		if (printf_putchar(' ', ps) > 0)
+			counter++;
+	}
+	
+	return (int) (counter + 1);
+}
+
+/** Print one formatted UTF-32 character.
+ *
+ * @param ch    Character to print.
+ * @param width Width modifier.
+ * @param flags Flags that change the way the character is printed.
+ *
+ * @return Number of characters printed, negative value on failure.
+ *
+ */
+static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps)
+{
+	count_t counter = 0;
+	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
+		while (--width > 0) {
 			/*
 			 * One space is consumed by the character itself, hence
 			 * the predecrement.
 			 */
+			if (printf_putchar(' ', ps) > 0)
+				counter++;
+		}
+	}
+	
+	if (printf_putwchar(ch, ps) > 0)
+		counter++;
+	
+	while (--width > 0) {
+		/*
+		 * One space is consumed by the character itself, hence
+		 * the predecrement.
+		 */
 		if (printf_putchar(' ', ps) > 0)
-			++counter;
-	}
-	
-	return ++counter;
-}
-
-/** Print string.
- *
- * @param s		String to be printed.
- * @param width		Width modifier.
- * @param precision	Precision modifier.
- * @param flags		Flags that modify the way the string is printed.
- *
- * @return		Number of characters printed, negative value on	failure.
- */ 
-static int print_string(char *s, int width, unsigned int precision,
-	uint64_t flags, struct printf_spec *ps)
-{
-	int counter = 0;
-	size_t size;
+			counter++;
+	}
+	
+	return (int) (counter + 1);
+}
+
+/** Print UTF-8 string.
+ *
+ * @param str       UTF-8 string to be printed.
+ * @param width     Width modifier.
+ * @param precision Precision modifier.
+ * @param flags     Flags that modify the way the string is printed.
+ *
+ * @return Number of UTF-8 characters printed, negative value on failure.
+ */
+static int print_utf8(char *str, int width, unsigned int precision,
+	uint32_t flags, printf_spec_t *ps)
+{
+	if (str == NULL)
+		return printf_putstr(nullstr, ps);
+	
+	/* Print leading spaces */
+	size_t size = strlen_utf8(str);
+	if (precision == 0)
+		precision = size;
+	
+	count_t counter = 0;
+	width -= precision;
+	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
+		while (width-- > 0) {
+			if (printf_putchar(' ', ps) == 1)
+				counter++;
+		}
+	}
+	
 	int retval;
-
-	if (s == NULL) {
-		return printf_putstr("(NULL)", ps);
-	}
-	
-	size = strlen(s);
-
-	/* print leading spaces */
-
-	if (precision == 0) 
+	size_t bytes = utf8_count_bytes(str, min(size, precision));
+	if ((retval = printf_putnchars_utf8(str, bytes, ps)) < 0)
+		return -counter;
+	
+	counter += retval;
+	
+	while (width-- > 0) {
+		if (printf_putchar(' ', ps) == 1)
+			counter++;
+	}
+	
+	return ((int) counter);
+}
+
+/** Print UTF-32 string.
+ *
+ * @param str       UTF-32 string to be printed.
+ * @param width     Width modifier.
+ * @param precision Precision modifier.
+ * @param flags     Flags that modify the way the string is printed.
+ *
+ * @return Number of UTF-32 characters printed, negative value on failure.
+ */
+static int print_utf32(wchar_t *str, int width, unsigned int precision,
+	uint32_t flags, printf_spec_t *ps)
+{
+	if (str == NULL)
+		return printf_putstr(nullstr, ps);
+	
+	/* Print leading spaces */
+	size_t size = strlen_utf32(str);
+	if (precision == 0)
 		precision = size;
-
+	
+	count_t counter = 0;
 	width -= precision;
-	
 	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
-		while (width-- > 0) { 	
-			if (printf_putchar(' ', ps) == 1)	
+		while (width-- > 0) {
+			if (printf_putchar(' ', ps) == 1)
 				counter++;
 		}
 	}
-
- 	if ((retval = printf_putnchars(s, min(size, precision), ps)) < 0) {
+	
+	int retval;
+	size_t bytes = min(size, precision) * sizeof(wchar_t);
+	if ((retval = printf_putnchars_utf32(str, bytes, ps)) < 0)
 		return -counter;
-	}
-	counter += retval;	
-
+	
+	counter += retval;
+	
 	while (width-- > 0) {
-		if (printf_putchar(' ', ps) == 1)	
-			++counter;
-	}
-	
-	return counter;
-}
-
+		if (printf_putchar(' ', ps) == 1)
+			counter++;
+	}
+	
+	return ((int) counter);
+}
 
 /** Print a number in a given base.
@@ -222,30 +331,31 @@
  * Print significant digits of a number in given base.
  *
- * @param num		Number to print.
- * @param widt		Width modifier.h
- * @param precision	Precision modifier.
- * @param base		Base to print the number in (must be between 2 and 16).
- * @param flags		Flags that modify the way the number is printed.	
- *
- * @return		Number of characters printed.
+ * @param num       Number to print.
+ * @param width     Width modifier.
+ * @param precision Precision modifier.
+ * @param base      Base to print the number in (must be between 2 and 16).
+ * @param flags     Flags that modify the way the number is printed.
+ *
+ * @return Number of characters printed.
  *
  */
 static int print_number(uint64_t num, int width, int precision, int base,
-    uint64_t flags, struct printf_spec *ps)
-{
-	char *digits = digits_small;
-	char d[PRINT_NUMBER_BUFFER_SIZE];
-	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 */
-	char sgn;
-	int retval;
-	int counter = 0;
-	
-	if (flags & __PRINTF_FLAG_BIGCHARS) 
-		digits = digits_big;	
-	
-	*ptr-- = 0; /* Put zero at end of string */
-
+    uint32_t flags, printf_spec_t *ps)
+{
+	char *digits;
+	if (flags & __PRINTF_FLAG_BIGCHARS)
+		digits = digits_big;
+	else
+		digits = digits_small;
+	
+	char data[PRINT_NUMBER_BUFFER_SIZE];
+	char *ptr = &data[PRINT_NUMBER_BUFFER_SIZE - 1];
+	
+	/* Size of number with all prefixes and signs */
+	int size = 0;
+	
+	/* Put zero at end of string */
+	*ptr-- = 0;
+	
 	if (num == 0) {
 		*ptr-- = '0';
@@ -258,13 +368,15 @@
 	}
 	
-	number_size = size;
-
+	/* Size of plain number */
+	int number_size = size;
+	
 	/*
-	 * Collect the sum of all prefixes/signs/... to calculate padding and
+	 * Collect the sum of all prefixes/signs/etc. to calculate padding and
 	 * leading zeroes.
 	 */
 	if (flags & __PRINTF_FLAG_PREFIX) {
 		switch(base) {
-		case 2:	/* Binary formating is not standard, but usefull */
+		case 2:
+			/* Binary formating is not standard, but usefull */
 			size += 2;
 			break;
@@ -277,6 +389,6 @@
 		}
 	}
-
-	sgn = 0;
+	
+	char sgn = 0;
 	if (flags & __PRINTF_FLAG_SIGNED) {
 		if (flags & __PRINTF_FLAG_NEGATIVE) {
@@ -291,36 +403,34 @@
 		}
 	}
-
-	if (flags & __PRINTF_FLAG_LEFTALIGNED) {
+	
+	if (flags & __PRINTF_FLAG_LEFTALIGNED)
 		flags &= ~__PRINTF_FLAG_ZEROPADDED;
-	}
-
+	
 	/*
-	 * If the number is leftaligned or precision is specified then
-	 * zeropadding is ignored.
+	 * If the number is left-aligned or precision is specified then
+	 * padding with zeros is ignored.
 	 */
 	if (flags & __PRINTF_FLAG_ZEROPADDED) {
-		if ((precision == 0) && (width > size)) {
+		if ((precision == 0) && (width > size))
 			precision = width - size + number_size;
-		}
-	}
-
-	/* print leading spaces */
+	}
+	
+	/* Print leading spaces */
 	if (number_size > precision) {
-		/* print the whole number not only a part */
+		/* Print the whole number, not only a part */
 		precision = number_size;
 	}
-
+	
 	width -= precision + size - number_size;
+	count_t counter = 0;
 	
 	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
-		while (width-- > 0) { 	
-			if (printf_putchar(' ', ps) == 1)	
+		while (width-- > 0) {
+			if (printf_putchar(' ', ps) == 1)
 				counter++;
 		}
 	}
 	
-	
-	/* print sign */
+	/* Print sign */
 	if (sgn) {
 		if (printf_putchar(sgn, ps) == 1)
@@ -328,9 +438,9 @@
 	}
 	
-	/* print prefix */
-	
+	/* Print prefix */
 	if (flags & __PRINTF_FLAG_PREFIX) {
 		switch(base) {
-		case 2:	/* Binary formating is not standard, but usefull */
+		case 2:
+			/* Binary formating is not standard, but usefull */
 			if (printf_putchar('0', ps) == 1)
 				counter++;
@@ -360,29 +470,26 @@
 		}
 	}
-
-	/* print leading zeroes */
+	
+	/* Print leading zeroes */
 	precision -= number_size;
-	while (precision-- > 0) { 	
+	while (precision-- > 0) {
 		if (printf_putchar('0', ps) == 1)
 			counter++;
 	}
-
-	
-	/* print number itself */
-
-	if ((retval = printf_putstr(++ptr, ps)) > 0) {
+	
+	/* Print the number itself */
+	int retval;
+	if ((retval = printf_putstr(++ptr, ps)) > 0)
 		counter += retval;
-	}
-	
-	/* print ending spaces */
-	
-	while (width-- > 0) { 	
-		if (printf_putchar(' ', ps) == 1)	
+	
+	/* Print tailing spaces */
+	
+	while (width-- > 0) {
+		if (printf_putchar(' ', ps) == 1)
 			counter++;
 	}
-
-	return counter;
-}
-
+	
+	return ((int) counter);
+}
 
 /** Print formatted string.
@@ -390,104 +497,106 @@
  * 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 ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION
  *
  * FLAGS:@n
- * 	- "#"	Force to print prefix.For \%o conversion, 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.
- * 
+ *  - "#" Force to print prefix. For \%o conversion, 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 the minimal width of a 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.
+ *  - Specify the minimal width of a 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.
- * 
+ *  - 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 unsigned short.@n
- * 	- ""	Signed or unsigned int (default value).@n
- * 	- "l"	Signed or unsigned long int.@n
- * 	- "ll"	Signed or unsigned long long int.@n
- * 
- * 
+ *  - "hh" Signed or unsigned char.@n
+ *  - "h"  Signed or unsigned short.@n
+ *  - ""   Signed or unsigned int (default value).@n
+ *  - "l"  Signed or unsigned long int.@n
+ *         If conversion is "c", the character is wchar_t (UTF-32).@n
+ *         If conversion is "s", the string is wchar_t * (UTF-32).@n
+ *  - "ll" Signed or unsigned long long int.@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 / \%#x
- *		for 32-bit or \%#X / \%#x for 64-bit 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.
- * 
+ *  - % Print percentile character itself.
+ *
+ *  - c Print single character. The character is expected to be plain
+ *      ASCII (e.g. only values 0 .. 127 are valid).@n
+ *      If type is "l", then the character is expected to be UTF-32
+ *      (e.g. values 0 .. 0x10ffff are valid).
+ *
+ *  - s Print zero terminated string. If a NULL value is passed as
+ *      value, "(NULL)" is printed instead.@n
+ *      The string is expected to be correctly encoded UTF-8 (or plain
+ *      ASCII, which is a subset of UTF-8).@n
+ *      If type is "l", then the string is expected to be correctly
+ *      encoded UTF-32.
+ *
+ *  - P, p Print value of a pointer. Void * value is expected and it is
+ *         printed in hexadecimal notation with prefix (as with \%#X / \%#x
+ *         for 32-bit or \%#X / \%#x for 64-bit 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 characters printed, negative value on failure.
- */
-int printf_core(const char *fmt, struct printf_spec *ps, va_list ap)
-{
-	int i = 0; /* index of the currently processed char from fmt */
-	int j = 0; /* 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 a numeric parameter will be printed */
-	uint64_t number; /* argument value */
-	size_t	size; /* byte size of integer parameter */
-	int width, precision;
-	uint64_t flags;
-	
-	counter = 0;
-		
-	while ((c = fmt[i])) {
-		/* control character */
-		if (c == '%') { 
-			/* print common characters if any processed */	
+ * @param fmt Formatting NULL terminated string (UTF-8 or plain ASCII).
+ *
+ * @return Number of UTF-8 characters printed, negative value on failure.
+ *
+ */
+int printf_core(const char *fmt, printf_spec_t *ps, va_list ap)
+{
+	index_t i = 0;  /* Index of the currently processed character from fmt */
+	index_t j = 0;  /* Index to the first not printed nonformating character */
+	
+	wchar_t uc;           /* Current UTF-32 character decoded from fmt */
+	count_t counter = 0;  /* Number of UTF-8 characters printed */
+	int retval;           /* Return values from nested functions */
+	
+	while ((uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT)) != 0) {
+		/* Control character */
+		if (uc == '%') {
+			/* Print common characters if any processed */
 			if (i > j) {
-				if ((retval = printf_putnchars(&fmt[j],
-				    (size_t)(i - j), ps)) < 0) { /* error */
+				if ((retval = printf_putnchars_utf8(&fmt[j], i - j, ps)) < 0) {
+					/* Error */
 					counter = -counter;
 					goto out;
@@ -495,13 +604,14 @@
 				counter += retval;
 			}
-		
+			
 			j = i;
-			/* parse modifiers */
-			flags = 0;
-			end = 0;
+			
+			/* Parse modifiers */
+			uint32_t flags = 0;
+			bool end = false;
 			
 			do {
-				++i;
-				switch (c = fmt[i]) {
+				i++;
+				switch ((uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT)) != 0) {
 				case '#':
 					flags |= __PRINTF_FLAG_PREFIX;
@@ -520,22 +630,26 @@
 					break;
 				default:
-					end = 1;
-				};	
-				
-			} while (end == 0);	
-			
-			/* width & '*' operator */
-			width = 0;
-			if (isdigit(fmt[i])) {
-				while (isdigit(fmt[i])) {
+					end = true;
+				};
+			} while (!end);
+			
+			/* Width & '*' operator */
+			int width = 0;
+			if (isdigit(uc)) {
+				while ((uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT)) != 0) {
+					if (!isdigit(uc))
+						break;
+					
 					width *= 10;
-					width += fmt[i++] - '0';
+					width += uc - '0';
+					i++;
 				}
-			} else if (fmt[i] == '*') {
-				/* get width value from argument list */
+			} else if (uc == '*') {
+				/* Get width value from argument list */
 				i++;
+				uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
 				width = (int) va_arg(ap, int);
 				if (width < 0) {
-					/* negative width sets '-' flag */
+					/* Negative width sets '-' flag */
 					width *= -1;
 					flags |= __PRINTF_FLAG_LEFTALIGNED;
@@ -543,84 +657,103 @@
 			}
 			
-			/* precision and '*' operator */	
-			precision = 0;
-			if (fmt[i] == '.') {
-				++i;
-				if (isdigit(fmt[i])) {
-					while (isdigit(fmt[i])) {
+			/* Precision and '*' operator */
+			int precision = 0;
+			if (uc == '.') {
+				i++;
+				uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
+				if (isdigit(uc)) {
+					while ((uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT)) != 0) {
+						if (!isdigit(uc))
+							break;
+						
 						precision *= 10;
-						precision += fmt[i++] - '0';
+						precision += uc - '0';
+						i++;
 					}
 				} else if (fmt[i] == '*') {
-					/*
-					 * Get precision value from the argument
-					 * list.
-					 */
+					/* Get precision value from the argument list */
 					i++;
+					uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
 					precision = (int) va_arg(ap, int);
 					if (precision < 0) {
-						/* ignore negative precision */
+						/* Ignore negative precision */
 						precision = 0;
 					}
 				}
 			}
-
-			switch (fmt[i++]) {
-			/** @todo unimplemented qualifiers:
-			 * t ptrdiff_t - ISO C 99
+			
+			qualifier_t qualifier;
+			
+			switch (uc) {
+			/** @todo Unimplemented qualifiers:
+			 *        t ptrdiff_t - ISO C 99
 			 */
-			case 'h':	/* char or short */
+			case 'h':
+				/* Char or short */
 				qualifier = PrintfQualifierShort;
-				if (fmt[i] == 'h') {
+				i++;
+				uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
+				if (uc == 'h') {
 					i++;
+					uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
 					qualifier = PrintfQualifierByte;
 				}
 				break;
-			case 'l':	/* long or long long*/
+			case 'l':
+				/* Long or long long */
 				qualifier = PrintfQualifierLong;
-				if (fmt[i] == 'l') {
+				i++;
+				uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
+				if (uc == 'l') {
 					i++;
+					uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
 					qualifier = PrintfQualifierLongLong;
 				}
 				break;
 			default:
-				/* default type */
-				qualifier = PrintfQualifierInt; 
-				--i;
-			}	
-			
-			base = 10;
-
-			switch (c = fmt[i]) {
-
+				/* Default type */
+				qualifier = PrintfQualifierInt;
+			}
+			
+			unsigned int base = 10;
+			
+			switch (uc) {
 			/*
-			* String and character conversions.
-			*/
+			 * String and character conversions.
+			 */
 			case 's':
-				if ((retval = print_string(va_arg(ap, char *),
-				    width, precision, flags, ps)) < 0) {
+				if (qualifier == PrintfQualifierLong)
+					retval = print_utf32(va_arg(ap, wchar_t *), width, precision, flags, ps);
+				else
+					retval = print_utf8(va_arg(ap, char *), width, precision, flags, ps);
+				
+				if (retval < 0) {
 					counter = -counter;
 					goto out;
-				};
-
+				}
+				
 				counter += retval;
-				j = i + 1; 
+				j = i + 1;
 				goto next_char;
 			case 'c':
-				c = va_arg(ap, unsigned int);
-				retval = print_char(c, width, flags, ps);
+				if (qualifier == PrintfQualifierLong)
+					retval = print_wchar(va_arg(ap, wchar_t), width, flags, ps);
+				else
+					retval = print_char(va_arg(ap, unsigned int), width, flags, ps);
+				
 				if (retval < 0) {
 					counter = -counter;
 					goto out;
 				};
-					
+				
 				counter += retval;
 				j = i + 1;
 				goto next_char;
-
-			/* 
+			
+			/*
 			 * Integer values
 			 */
-			case 'P': /* pointer */
+			case 'P':
+				/* Pointer */
 				flags |= __PRINTF_FLAG_BIGCHARS;
 			case 'p':
@@ -628,6 +761,6 @@
 				base = 16;
 				qualifier = PrintfQualifierPointer;
-				break;	
-			case 'b': 
+				break;
+			case 'b':
 				base = 2;
 				break;
@@ -637,5 +770,5 @@
 			case 'd':
 			case 'i':
-				flags |= __PRINTF_FLAG_SIGNED;  
+				flags |= __PRINTF_FLAG_SIGNED;
 			case 'u':
 				break;
@@ -645,8 +778,10 @@
 				base = 16;
 				break;
-			/* percentile itself */
-			case '%': 
+			
+			/* Percentile itself */
+			case '%':
 				j = i;
 				goto next_char;
+			
 			/*
 			 * Bad formatting.
@@ -657,10 +792,10 @@
 				 * so we will print whole bad format sequence.
 				 */
-				goto next_char;		
-			}
-		
-		
-		/* Print integers */
-			/* print number */
+				goto next_char;
+			}
+			
+			/* Print integers */
+			size_t size;
+			uint64_t number;
 			switch (qualifier) {
 			case PrintfQualifierByte:
@@ -688,5 +823,6 @@
 				number = (uint64_t) (unsigned long) va_arg(ap, void *);
 				break;
-			default: /* Unknown qualifier */
+			default:
+				/* Unknown qualifier */
 				counter = -counter;
 				goto out;
@@ -696,5 +832,5 @@
 				if (number & (0x1 << (size * 8 - 1))) {
 					flags |= __PRINTF_FLAG_NEGATIVE;
-				
+					
 					if (size == sizeof(uint64_t)) {
 						number = -((int64_t) number);
@@ -708,5 +844,5 @@
 				}
 			}
-
+			
 			if ((retval = print_number(number, width, precision,
 			    base, flags, ps)) < 0) {
@@ -714,25 +850,24 @@
 				goto out;
 			}
-
+			
 			counter += retval;
 			j = i + 1;
-		}	
+		}
 next_char:
-			
-		++i;
+		
+		i++;
 	}
 	
 	if (i > j) {
-		if ((retval = printf_putnchars(&fmt[j], (unative_t) (i - j),
-		    ps)) < 0) { /* error */
+		if ((retval = printf_putnchars_utf8(&fmt[j], i - j, ps)) < 0) {
+			/* Error */
 			counter = -counter;
 			goto out;
-			
 		}
 		counter += retval;
 	}
-
+	
 out:
-	return counter;
+	return ((int) counter);
 }
 
Index: kernel/generic/src/printf/snprintf.c
===================================================================
--- kernel/generic/src/printf/snprintf.c	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/src/printf/snprintf.c	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -43,7 +43,7 @@
 	va_start(args, fmt);
 	ret = vsnprintf(str, size, fmt, args);
-
+	
 	va_end(args);
-
+	
 	return ret;
 }
Index: kernel/generic/src/printf/vprintf.c
===================================================================
--- kernel/generic/src/printf/vprintf.c	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/src/printf/vprintf.c	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -40,26 +40,56 @@
 #include <arch/types.h>
 #include <typedefs.h>
+#include <string.h>
 
-SPINLOCK_INITIALIZE(printf_lock);			/**< vprintf spinlock */
+SPINLOCK_INITIALIZE(printf_lock);  /**< vprintf spinlock */
 
-static int vprintf_write(const char *str, size_t count, void *unused)
+static int vprintf_write_utf8(const char *str, size_t size, void *data)
 {
-	size_t i;
-	for (i = 0; i < count; i++)
-		putchar(str[i]);
-	return i;
+	index_t index = 0;
+	index_t chars = 0;
+	
+	while (index < size) {
+		putchar(utf8_decode(str, &index, size - 1));
+		index++;
+		chars++;
+	}
+	
+	return chars;
 }
 
-int puts(const char *s)
+static int vprintf_write_utf32(const wchar_t *str, size_t size, void *data)
 {
-	size_t i;
-	for (i = 0; s[i] != 0; i++)
-		putchar(s[i]);
-	return i;
+	index_t index = 0;
+	
+	while (index < (size / sizeof(wchar_t))) {
+		putchar(str[index]);
+		index++;
+	}
+	
+	return index;
+}
+
+int puts(const char *str)
+{
+	index_t index = 0;
+	index_t chars = 0;
+	wchar_t uc;
+	
+	while ((uc = utf8_decode(str, &index, UTF8_NO_LIMIT)) != 0) {
+		putchar(uc);
+		index++;
+		chars++;
+	}
+	
+	return chars;
 }
 
 int vprintf(const char *fmt, va_list ap)
 {
-	struct printf_spec ps = {(int(*)(void *, size_t, void *)) vprintf_write, NULL};
+	printf_spec_t ps = {
+		vprintf_write_utf8,
+		vprintf_write_utf32,
+		NULL
+	};
 	
 	ipl_t ipl = interrupts_disable();
Index: kernel/generic/src/printf/vsnprintf.c
===================================================================
--- kernel/generic/src/printf/vsnprintf.c	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/src/printf/vsnprintf.c	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -35,60 +35,147 @@
 #include <print.h>
 #include <printf/printf_core.h>
+#include <string.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 */
-};
+typedef struct {
+	size_t size;    /* Total size of the buffer (in bytes) */
+	size_t len;     /* Number of already used bytes */
+	char *dst;      /* Destination */
+} vsnprintf_data_t;
 
-/** Write string to given buffer.
- * Write at most data->size characters including trailing zero. According to C99, snprintf() has 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 the 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!)
+/** Write UTF-8 string to given buffer.
+ *
+ * Write at most data->size plain characters including trailing zero.
+ * According to C99, snprintf() has to return number of characters that
+ * would have been written if enough space had been available. Hence
+ * the return value is not the number of actually printed characters
+ * but size of the input string.
+ *
+ * @param str  Source UTF-8 string to print.
+ * @param size Number of plain characters in str.
+ * @param data Structure describing destination string, counter
+ *             of used space and total string size.
+ *
+ * @return Number of UTF-8 characters to print (not characters actually
+ *         printed).
+ *
  */
-static int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data)
+static int vsnprintf_write_utf8(const char *str, size_t size, vsnprintf_data_t *data)
 {
-	size_t i;
-	i = data->size - data->len;
-
-	if (i == 0) {
-		return count;
+	size_t left = data->size - data->len;
+	
+	if (left == 0)
+		return ((int) size);
+	
+	if (left == 1) {
+		/* We have only one free byte left in buffer
+		 * -> store trailing zero
+		 */
+		data->dst[data->size - 1] = 0;
+		data->len = data->size;
+		return ((int) size);
 	}
 	
-	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;
-		return count;
+	if (left <= size) {
+		/* We have not enought space for whole string
+		 * with the trailing zero => print only a part
+		 * of string
+		 */
+		index_t index = 0;
+		
+		while (index < size) {
+			wchar_t uc = utf8_decode(str, &index, size - 1);
+			
+			if (!utf8_encode(uc, data->dst, &data->len, data->size - 1))
+				break;
+			
+			data->len++;
+			index++;
+		}
+		
+		/* Put trailing zero at end, but not count it
+		 * into data->len so it could be rewritten next time
+		 */
+		data->dst[data->len] = 0;
+		
+		return ((int) size);
 	}
 	
-	if (i <= count) {
-		/* 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;
+	/* Buffer is big enought to print the whole string */
+	memcpy((void *)(data->dst + data->len), (void *) str, size);
+	data->len += size;
+	
+	/* Put trailing zero at end, but not count it
+	 * into data->len so it could be rewritten next time
+	 */
+	data->dst[data->len] = 0;
+	
+	return ((int) size);
+}
+
+/** Write UTF-32 string to given buffer.
+ *
+ * Write at most data->size plain characters including trailing zero.
+ * According to C99, snprintf() has to return number of characters that
+ * would have been written if enough space had been available. Hence
+ * the return value is not the number of actually printed characters
+ * but size of the input string.
+ *
+ * @param str  Source UTF-32 string to print.
+ * @param size Number of bytes in str.
+ * @param data Structure describing destination string, counter
+ *             of used space and total string size.
+ *
+ * @return Number of UTF-8 characters to print (not characters actually
+ *         printed).
+ *
+ */
+static int vsnprintf_write_utf32(const wchar_t *str, size_t size, vsnprintf_data_t *data)
+{
+	index_t index = 0;
+	
+	while (index < (size / sizeof(wchar_t))) {
+		size_t left = data->size - data->len;
+		
+		if (left == 0)
+			return ((int) size);
+		
+		if (left == 1) {
+			/* We have only one free byte left in buffer
+			 * -> store trailing zero
+			 */
+			data->dst[data->size - 1] = 0;
 			data->len = data->size;
-			return count;
+			return ((int) size);
+		}
+		
+		if (!utf8_encode(str[index], data->dst, &data->len, data->size - 1))
+			break;
+		
+		data->len++;
+		index++;
 	}
 	
-	/* Buffer is big enought to print whole string */
-	memcpy((void *)(data->string + data->len), (void *)str, count);
-	data->len += count;
-	/* 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;	
+	/* Put trailing zero at end, but not count it
+	 * into data->len so it could be rewritten next time
+	 */
+	data->dst[data->len] = 0;
+	
+	return ((int) size);
 }
 
 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};
-
+	vsnprintf_data_t data = {
+		size,
+		0,
+		str
+	};
+	printf_spec_t ps = {
+		(int(*) (const char *, size_t, void *)) vsnprintf_write_utf8,
+		(int(*) (const wchar_t *, size_t, void *)) vsnprintf_write_utf32,
+		&data
+	};
+	
 	/* Print 0 at end of string - fix the case that nothing will be printed */
 	if (size > 0)
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision 74c8da2cccbb4fc6d0f008bd445bdcecfa733400)
+++ kernel/generic/src/syscall/syscall.c	(revision eec616bc34e4233a5e002814ad0f802ef63af58d)
@@ -42,5 +42,4 @@
 #include <mm/as.h>
 #include <print.h>
-#include <putchar.h>
 #include <arch.h>
 #include <debug.h>
