19 #include <core/syscall.h>
20 #include <libc/stdio.h>
22 static const char digits[] =
"0123456789abcdef";
24 #define INT_UNSIGNED 1
26 #define FLOAT_SIGNED 3
27 #define DOUBLE_PRECISION (6)
32 #define MY_BUF_SIZE 128
40 char buff[MY_BUF_SIZE];
53 typedef int (*t_fmtfun)(
union u_arg *arg,
struct s_file *file,
int flags);
66 static void my_fflush(
struct s_file *file)
68 pok_syscall2 (POK_SYSCALL_CONSWRITE, (uint32_t)file->buff, file->pos);
72 static struct s_file* init_buffered_output(
void)
80 static void my_putc(
char c,
struct s_file *file)
82 file->buff[file->pos++] = c;
83 if (file->pos == MY_BUF_SIZE)
87 static void close_buffered_output(
struct s_file *file)
96 static int conv (uint32_t n,
int base,
int dig[])
109 static int my_printnbr_base (uint32_t n,
123 count = i = conv(n, card, digits);
126 my_putc(base[digits[i]], file);
131 static int print_int (
union u_arg* value,
struct s_file* file,
int flags)
135 if (value->sint == 0)
140 if (flags == INT_SIGNED)
145 value->uint = -value->sint;
150 value->uint = value->sint;
153 return my_printnbr_base(value->uint, digits, 10, file) + sh;
157 static int print_float (
union u_arg* value,
struct s_file* file,
int flags)
159 int floor = value->vdouble;
160 uint32_t fractional = 0;
165 res += my_printnbr_base(floor, digits, 10, file);
169 while (precision < DOUBLE_PRECISION)
171 fractional = (value->vdouble - floor) * decimal;
173 res += my_printnbr_base(fractional, digits, 10, file);
182 static int print_str (
union u_arg* value,
struct s_file* file,
int flags)
185 char* s = value->ptr;
188 for (; *s; ++count, ++s)
193 static int print_char (
union u_arg* value,
struct s_file* file,
int flags)
203 static int print_base(
union u_arg* value,
struct s_file* file,
int flags)
205 return my_printnbr_base(value->uint, digits, flags, file);
208 static const struct s_format formats[] =
210 {
'd', print_int, INT_SIGNED },
211 {
'f', print_float, FLOAT_SIGNED },
212 {
'i', print_int, INT_SIGNED },
213 {
'u', print_int, INT_UNSIGNED },
214 {
's', print_str, 0 },
215 {
'c', print_char, 0 },
216 {
'o', print_base, BASE_OCT },
217 {
'x', print_base, BASE_HEX },
221 static int special_char(
char fmt,
union u_arg* value,
struct s_file* file)
225 for (i = 0; formats[i].fun; ++i)
227 if (formats[i].ch == fmt)
234 return formats[i].fun(value, file, formats[i].flags);
245 return 1 + (fmt !=
'%');
253 int vprintf(
const char* format, va_list args)
262 for (file = init_buffered_output(); *format; format += (*format ==
'%' ? 2 : 1))
270 if (*(format + 1) !=
'%')
272 switch (*(format + 1))
275 arg.vdouble = va_arg (args,
double);
279 arg.value = va_arg (args, uint32_t);
283 count += special_char(*(format + 1), &arg, file);
287 my_putc(*format, file);
292 close_buffered_output(file);
296 int printf(
const char *format, ...)
301 va_start(args, format);
302 res = vprintf (format, args);