157 lines
2.8 KiB
C
157 lines
2.8 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
int kputchar(int c) {
|
|
terminal_putchar(c);
|
|
return (unsigned char)c;
|
|
}
|
|
|
|
int kputs(const char *s) {
|
|
int i = 0;
|
|
while(s[i] != '\0') {
|
|
kputchar(s[i]);
|
|
i++;
|
|
}
|
|
kputchar('\n');
|
|
return 1; // FIXME
|
|
}
|
|
|
|
int kvsnprintf(char *restrict s, size_t n, const char *restrict format, va_list ap) {
|
|
char *str;
|
|
int value;
|
|
size_t size = 0;
|
|
for (size_t i = 0; i < strlen(format) && size < n-1; i++) {
|
|
if (format[i] == '%') {
|
|
i++;
|
|
switch(format[i]) {
|
|
case 'c':
|
|
s[size] = (char) va_arg(ap, int);
|
|
size++;
|
|
break;
|
|
case 's':
|
|
str = va_arg(ap, char *);
|
|
for (size_t j = 0; j < strlen(str); j++) {
|
|
s[size] = str[j];
|
|
size++;
|
|
}
|
|
break;
|
|
case 'd':
|
|
value = va_arg(ap, int);
|
|
if (value == 0) {
|
|
s[size] = '0';
|
|
size++;
|
|
} if (value < 0) {
|
|
s[size] = '-';
|
|
value *= (-1);
|
|
size++;
|
|
}
|
|
|
|
long long power = 1;
|
|
|
|
while (value > power)
|
|
power *= 10;
|
|
|
|
if (power >= 10)
|
|
power /= 10;
|
|
|
|
while (value != 0) {
|
|
int digit = (int)(value / power);
|
|
s[size] = '0' + digit;
|
|
size++;
|
|
if (digit != 0)
|
|
value = value - digit * power;
|
|
if (power != 1)
|
|
power /= 10;
|
|
}
|
|
break;
|
|
case 'x':
|
|
value = va_arg(ap, int);
|
|
if (value == 0) {
|
|
s[size] = '0';
|
|
size++;
|
|
}
|
|
|
|
power = 1;
|
|
|
|
while (value > power)
|
|
power *= 16;
|
|
|
|
if (power >= 16)
|
|
power /= 16;
|
|
|
|
while (value != 0) {
|
|
int digit = (int)(value / power);
|
|
if (digit < 10)
|
|
s[size] = '0' + digit;
|
|
else if (digit == 10)
|
|
s[size] = 'a';
|
|
else if (digit == 11)
|
|
s[size] = 'b';
|
|
else if (digit == 12)
|
|
s[size] = 'c';
|
|
else if (digit == 13)
|
|
s[size] = 'd';
|
|
else if (digit == 14)
|
|
s[size] = 'e';
|
|
else if (digit == 15)
|
|
s[size] = 'f';
|
|
size++;
|
|
if (digit != 0)
|
|
value = value - digit * power;
|
|
if (power != 1)
|
|
power /= 16;
|
|
}
|
|
break;
|
|
}
|
|
} else {
|
|
s[size] = format[i];
|
|
size++;
|
|
}
|
|
}
|
|
s[size] = '\0';
|
|
return size;
|
|
}
|
|
|
|
int ksnprintf(char *restrict s, size_t n, const char *restrict format, ...) {
|
|
int size;
|
|
va_list ap;
|
|
va_start(ap, format);
|
|
size = kvsnprintf(s, n, format, ap);
|
|
va_end(ap);
|
|
return size;
|
|
}
|
|
|
|
int kvsprintf(char *restrict s, const char *restrict format, va_list ap) {
|
|
size_t n = strlen(s);
|
|
return kvsnprintf(s, n, format, ap);
|
|
}
|
|
|
|
int ksprintf(char *restrict s, const char *restrict format, ...) {
|
|
int size;
|
|
va_list ap;
|
|
va_start(ap, format);
|
|
size = kvsprintf(s, format, ap);
|
|
va_end(ap);
|
|
return size;
|
|
}
|
|
|
|
int kvprintf(const char *restrict format, va_list ap) {
|
|
char s[1024] = ""; // FIXME
|
|
int size = kvsprintf(s, format, ap);
|
|
int i = 0;
|
|
while (i < size) {
|
|
kputchar(s[i]);
|
|
i++;
|
|
}
|
|
return size;
|
|
}
|
|
|
|
int kprintf(const char *restrict format, ...) {
|
|
int size;
|
|
va_list ap;
|
|
va_start(ap, format);
|
|
size = kvprintf(format, ap);
|
|
va_end(ap);
|
|
return size;
|
|
}
|