1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
// MIT License, Copyright (c) 2020 Marvin Borner
#include <arg.h>
#include <assert.h>
#include <conv.h>
#include <def.h>
#include <mem.h>
#include <serial.h>
#include <str.h>
static void append(char *dest, char *src, int index)
{
for (u32 i = index; i < strlen(src) + index; i++)
dest[i] = src[i - index];
dest[index + strlen(src)] = 0;
}
int vsprintf(char *str, const char *format, va_list ap)
{
u8 ready_to_format = 0;
int i = 0;
char buf = 0;
char format_buffer[20] = { '\0' };
for (; *format; format++) {
if (ready_to_format) {
ready_to_format = 0;
if (*format == '%') {
str[i] = '%';
continue;
}
buf = *format;
// TODO: Improve this repetitive code
if (buf == 's') {
char *string = va_arg(ap, char *);
assert(string);
append(str, string, i);
i = strlen(str);
} else if (buf == 'x') {
conv_base(va_arg(ap, u32), format_buffer, 16, 0);
append(str, format_buffer, i);
i = strlen(str);
} else if (buf == 'd' || buf == 'i') {
conv_base(va_arg(ap, s32), format_buffer, 10, 1);
append(str, format_buffer, i);
i = strlen(str);
} else if (buf == 'u') {
conv_base(va_arg(ap, u32), format_buffer, 10, 0);
append(str, format_buffer, i);
i = strlen(str);
} else if (buf == 'o') {
conv_base(va_arg(ap, u32), format_buffer, 8, 0);
append(str, format_buffer, i);
i = strlen(str);
} else if (buf == 'b') {
conv_base(va_arg(ap, u32), format_buffer, 2, 0);
append(str, format_buffer, i);
i = strlen(str);
} else if (buf == 'c') {
str[i] = (char)va_arg(ap, int);
i++;
}
} else {
if (*format == '%')
ready_to_format = 1;
else {
str[i] = *format;
i++;
}
}
format_buffer[0] = '\0';
}
return strlen(str);
}
int vprintf(const char *format, va_list ap)
{
char buf[1024] = { 0 };
int len = vsprintf(buf, format, ap);
serial_print(buf); // TODO: Remove temporary serial print
return len;
}
// TODO: Fix printf for *very* large strings (serial works)
int printf(const char *format, ...)
{
va_list ap;
va_start(ap, format);
int len = vprintf(format, ap);
va_end(ap);
return len;
}
int print(const char *str)
{
serial_print(str);
return strlen(str);
}
|