Much better (and more compliant) printk.
This commit is contained in:
parent
905a8a05a1
commit
1ef6bb95b3
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
int strindexof(char c, const char *str);
|
|
||||||
size_t strlen(const char *str);
|
size_t strlen(const char *str);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,11 +40,11 @@ void brados_main(uint32_t multiMagic, uint32_t multiAddr)
|
|||||||
uint64_t lastAddr = 0;
|
uint64_t lastAddr = 0;
|
||||||
for (int i = 0; i < numEntries; i++) {
|
for (int i = 0; i < numEntries; i++) {
|
||||||
if (memmap[i].base_addr != lastAddr) {
|
if (memmap[i].base_addr != lastAddr) {
|
||||||
printk(&term, "%llx - %llx: Unknown\n", lastAddr, memmap[i].base_addr - 1);
|
printk(&term, "%#llx - %#llx: Unknown\n", lastAddr, memmap[i].base_addr - 1);
|
||||||
lastAddr = memmap[i].base_addr;
|
lastAddr = memmap[i].base_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(&term, "%llx - %llx: ", memmap[i].base_addr, memmap[i].base_addr + memmap[i].length - 1);
|
printk(&term, "%#llx - %#llx: ", memmap[i].base_addr, memmap[i].base_addr + memmap[i].length - 1);
|
||||||
if (memmap[i].type == 1)
|
if (memmap[i].type == 1)
|
||||||
printk(&term, "Available\n");
|
printk(&term, "Available\n");
|
||||||
else
|
else
|
||||||
@ -55,5 +55,5 @@ void brados_main(uint32_t multiMagic, uint32_t multiAddr)
|
|||||||
|
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
term_writeStr(&term, "\nDone.");
|
printk(&term, "\nDone.");
|
||||||
}
|
}
|
||||||
|
719
kernel/printk.c
719
kernel/printk.c
@ -1,5 +1,6 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <brados/printk.h>
|
#include <brados/printk.h>
|
||||||
#include <brados/string.h>
|
#include <brados/string.h>
|
||||||
@ -9,7 +10,7 @@ const char *BASE16 = "0123456789ABCDEF";
|
|||||||
const char *BASE16L = "0123456789abcdef";
|
const char *BASE16L = "0123456789abcdef";
|
||||||
|
|
||||||
// Print an unsigned number as a string; return the number of characters printed
|
// Print an unsigned number as a string; return the number of characters printed
|
||||||
static int printNum(struct vgastate *term, unsigned long long num, unsigned int base, const char *digits)
|
static int printNum(struct vgastate *term, uintmax_t num, unsigned int base, const char *digits)
|
||||||
{
|
{
|
||||||
if (base > strlen(digits))
|
if (base > strlen(digits))
|
||||||
return 0;
|
return 0;
|
||||||
@ -23,6 +24,18 @@ static int printNum(struct vgastate *term, unsigned long long num, unsigned int
|
|||||||
return numPrinted;
|
return numPrinted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determines the printed length of a number
|
||||||
|
static unsigned int numLen(uintmax_t num, unsigned int base)
|
||||||
|
{
|
||||||
|
unsigned int len = 1;
|
||||||
|
while (num >= base) {
|
||||||
|
len++;
|
||||||
|
num /= base;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
// Print a formatted string to the given terminal
|
// Print a formatted string to the given terminal
|
||||||
int printk(struct vgastate *term, const char *fmt, ...)
|
int printk(struct vgastate *term, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -30,189 +43,551 @@ int printk(struct vgastate *term, const char *fmt, ...)
|
|||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|
||||||
size_t i = 0;
|
// The bits of 'mode' explained:
|
||||||
while (i < strlen(fmt)) {
|
// 0: Whether we are printing characters normally or parsing the format
|
||||||
if (fmt[i] == '%') {
|
// 1: Whether we are still parsing flags
|
||||||
i++;
|
// 2: Whether we are looking at width or precision (have we seen a .)
|
||||||
int end = 0, lng = 0;
|
// 3: + flag
|
||||||
|
// 4: space flag
|
||||||
|
// 5: - flag
|
||||||
|
// 6: # flag
|
||||||
|
// 7: 0 flag
|
||||||
|
uint8_t mode = 0;
|
||||||
|
int length = 0;
|
||||||
|
unsigned int width = 0, precision = 0;
|
||||||
|
|
||||||
while (end == 0) {
|
for (size_t i = 0; i < strlen(fmt); i++) {
|
||||||
switch (fmt[i]) {
|
if (mode % 2 == 0) {
|
||||||
// Print a percent sign
|
// Begin parsing format if we reach a '%'
|
||||||
case '%':
|
if (fmt[i] == '%') {
|
||||||
term_putChar(term, '%');
|
mode |= 0x01;
|
||||||
numPrinted++;
|
// Or just print the character if we're not parsing
|
||||||
end = 1;
|
} else {
|
||||||
|
term_putChar(term, fmt[i]);
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (fmt[i]) {
|
||||||
|
case '%':
|
||||||
|
// Print a percent sign
|
||||||
|
term_putChar(term, '%');
|
||||||
|
numPrinted++;
|
||||||
|
mode = 0;
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
// Set the plus flag
|
||||||
|
if ((mode >> 1) % 2 == 0)
|
||||||
|
mode |= 0x08;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
// Set the space flag
|
||||||
|
if ((mode >> 1) % 2 == 0)
|
||||||
|
mode |= 0x10;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
// Set the left-align flag
|
||||||
|
if ((mode >> 1) % 2 == 0)
|
||||||
|
mode |= 0x20;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case '#':
|
||||||
|
// Set the alternate flag
|
||||||
|
if ((mode >> 1) % 2 == 0)
|
||||||
|
mode |= 0x40;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
// Set the zero-pad flag
|
||||||
|
if ((mode >> 1) % 2 == 0)
|
||||||
|
mode |= 0x80;
|
||||||
|
// Next digit in width specifier
|
||||||
|
else if ((mode >> 2) % 2 == 0)
|
||||||
|
width *= 10;
|
||||||
|
// Next digit in precision specifier
|
||||||
|
else
|
||||||
|
precision *= 10;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
case '8':
|
||||||
|
case '9':
|
||||||
|
// Next digit in width specifier
|
||||||
|
if ((mode >> 2) % 2 == 0) {
|
||||||
|
mode |= 0x02;
|
||||||
|
width *= 10;
|
||||||
|
width += (fmt[i] - 48); // 0 = ascii 48
|
||||||
|
// Next digit in precision specifier
|
||||||
|
} else {
|
||||||
|
precision *= 10;
|
||||||
|
precision += (fmt[i] - 48);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
// Delimit width and precision
|
||||||
|
if ((mode >> 2) % 2 == 0)
|
||||||
|
mode |= 0x06;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
// Denotes a short or char argument
|
||||||
|
mode |= 0x06;
|
||||||
|
length--;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
// Denotes a long or long long argument
|
||||||
|
mode |= 0x06;
|
||||||
|
length++;
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
// Denotes a size_t argument
|
||||||
|
mode |= 0x06;
|
||||||
|
length = 3;
|
||||||
|
break;
|
||||||
|
case 'j':
|
||||||
|
// Denotes a intmax_t argument
|
||||||
|
mode |= 0x06;
|
||||||
|
length = 4;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
// Denotes a ptrdiff_t argument
|
||||||
|
mode |= 0x06;
|
||||||
|
length = 5;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
// Print a signed integer
|
||||||
|
case 'i': {
|
||||||
|
intmax_t num;
|
||||||
|
uintmax_t unum;
|
||||||
|
|
||||||
|
// Pull the argument from the list
|
||||||
|
switch (length) {
|
||||||
|
case 1:
|
||||||
|
num = va_arg(args, long);
|
||||||
break;
|
break;
|
||||||
// Print a single character
|
case 2:
|
||||||
case 'c':
|
num = va_arg(args, long long);
|
||||||
term_putChar(term, (char) va_arg(args, int));
|
|
||||||
numPrinted++;
|
|
||||||
end = 1;
|
|
||||||
break;
|
break;
|
||||||
// Print an integer number
|
case 3:
|
||||||
case 'd':
|
num = va_arg(args, size_t);
|
||||||
case 'i':
|
|
||||||
switch (lng) {
|
|
||||||
case 0: {
|
|
||||||
int d;
|
|
||||||
d = va_arg(args, int);
|
|
||||||
if (d < 0) {
|
|
||||||
term_putChar(term, '-');
|
|
||||||
numPrinted++;
|
|
||||||
d *= -1;
|
|
||||||
}
|
|
||||||
numPrinted += printNum(term, (unsigned int) d, 10, BASE16);
|
|
||||||
break;
|
|
||||||
} case 1: {
|
|
||||||
long ld;
|
|
||||||
ld = va_arg(args, long);
|
|
||||||
if (ld < 0) {
|
|
||||||
term_putChar(term, '-');
|
|
||||||
numPrinted++;
|
|
||||||
ld *= -1;
|
|
||||||
}
|
|
||||||
numPrinted += printNum(term, (unsigned long) ld, 10, BASE16);
|
|
||||||
break;
|
|
||||||
} default: {
|
|
||||||
long long lld;
|
|
||||||
lld = va_arg(args, long long);
|
|
||||||
if (lld < 0) {
|
|
||||||
term_putChar(term, '-');
|
|
||||||
numPrinted++;
|
|
||||||
lld *= -1;
|
|
||||||
}
|
|
||||||
numPrinted += printNum(term, (unsigned long long) lld, 10, BASE16);
|
|
||||||
break;
|
|
||||||
}}
|
|
||||||
end = 1;
|
|
||||||
break;
|
break;
|
||||||
// Expect a long (long) value
|
case 4:
|
||||||
case 'l':
|
num = va_arg(args, intmax_t);
|
||||||
lng++;
|
|
||||||
break;
|
break;
|
||||||
// Store the number of printed characters
|
case 5:
|
||||||
case 'n': {
|
num = va_arg(args, ptrdiff_t);
|
||||||
int *n;
|
|
||||||
n = va_arg(args, int *);
|
|
||||||
*n = numPrinted;
|
|
||||||
end = 1;
|
|
||||||
break;
|
break;
|
||||||
// Print an unsigned integer in octal form
|
default:
|
||||||
} case 'o':
|
num = va_arg(args, int);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get unsigned version
|
||||||
|
if (num < 0)
|
||||||
|
unum = num * -1;
|
||||||
|
else
|
||||||
|
unum = num;
|
||||||
|
|
||||||
|
// Get the length of the printed number
|
||||||
|
unsigned int len = numLen(unum, 10);
|
||||||
|
|
||||||
|
// Get the length of the printed number with formatting
|
||||||
|
unsigned int flen = len;
|
||||||
|
if (precision > len)
|
||||||
|
flen += (precision - len);
|
||||||
|
if (num < 0)
|
||||||
|
flen++;
|
||||||
|
if (num >= 0 && ((mode >> 3) % 2 == 1 || (mode >> 4) % 2 == 1))
|
||||||
|
flen++;
|
||||||
|
|
||||||
|
// If specified, print preceding space padding
|
||||||
|
if ((mode >> 5) % 2 == 0) {
|
||||||
|
if (precision > 0 || (mode >> 7) % 2 == 0) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If specified print the sign
|
||||||
|
if (num < 0) {
|
||||||
|
term_putChar(term, '-');
|
||||||
|
numPrinted++;
|
||||||
|
} else if ((mode >> 3) % 2 == 1) {
|
||||||
|
term_putChar(term, '+');
|
||||||
|
numPrinted++;
|
||||||
|
} else if ((mode >> 4) % 2 == 1) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If specified, print the precision 0s
|
||||||
|
if (precision > 0) {
|
||||||
|
for (int j = precision - len; j > 0; j--) {
|
||||||
|
term_putChar(term, '0');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
} else if ((mode >> 7) % 2 == 1) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
term_putChar(term, '0');
|
term_putChar(term, '0');
|
||||||
numPrinted++;
|
numPrinted++;
|
||||||
switch (lng) {
|
|
||||||
case 0: {
|
|
||||||
unsigned int o;
|
|
||||||
o = va_arg(args, unsigned int);
|
|
||||||
numPrinted += printNum(term, o, 8, BASE16);
|
|
||||||
break;
|
|
||||||
} case 1: {
|
|
||||||
unsigned long lo;
|
|
||||||
lo = va_arg(args, unsigned long);
|
|
||||||
numPrinted += printNum(term, lo, 8, BASE16);
|
|
||||||
break;
|
|
||||||
} default: {
|
|
||||||
unsigned long long llo;
|
|
||||||
llo = va_arg(args, unsigned long long);
|
|
||||||
numPrinted += printNum(term, llo, 8, BASE16);
|
|
||||||
break;
|
|
||||||
}}
|
|
||||||
end = 1;
|
|
||||||
break;
|
|
||||||
// Print a null-terminated string
|
|
||||||
case 's': {
|
|
||||||
char *s;
|
|
||||||
s = va_arg(args, char *);
|
|
||||||
term_writeStr(term, s);
|
|
||||||
numPrinted += strlen(s);
|
|
||||||
end = 1;
|
|
||||||
break;
|
|
||||||
// Print an unsigned integer value
|
|
||||||
} case 'u':
|
|
||||||
switch (lng) {
|
|
||||||
case 0: {
|
|
||||||
unsigned int u;
|
|
||||||
u = va_arg(args, unsigned int);
|
|
||||||
numPrinted += printNum(term, u, 10, BASE16);
|
|
||||||
break;
|
|
||||||
} case 1: {
|
|
||||||
unsigned long lu;
|
|
||||||
lu = va_arg(args, unsigned long);
|
|
||||||
numPrinted += printNum(term, lu, 10, BASE16);
|
|
||||||
break;
|
|
||||||
} default: {
|
|
||||||
unsigned long long llu;
|
|
||||||
llu = va_arg(args, unsigned long long);
|
|
||||||
numPrinted += printNum(term, llu, 10, BASE16);
|
|
||||||
break;
|
|
||||||
}}
|
|
||||||
end = 1;
|
|
||||||
break;
|
|
||||||
// Print an unsigned integer in lower hex form
|
|
||||||
case 'x':
|
|
||||||
term_writeStr(term, "0x");
|
|
||||||
numPrinted += 2;
|
|
||||||
switch (lng) {
|
|
||||||
case 0: {
|
|
||||||
unsigned int x;
|
|
||||||
x = va_arg(args, unsigned int);
|
|
||||||
numPrinted += printNum(term, x, 16, BASE16L);
|
|
||||||
break;
|
|
||||||
} case 1: {
|
|
||||||
unsigned long lx;
|
|
||||||
lx = va_arg(args, unsigned long);
|
|
||||||
numPrinted += printNum(term, lx, 16, BASE16L);
|
|
||||||
break;
|
|
||||||
} default: {
|
|
||||||
unsigned long long llx;
|
|
||||||
llx = va_arg(args, unsigned long long);
|
|
||||||
numPrinted += printNum(term, llx, 16, BASE16L);
|
|
||||||
break;
|
|
||||||
}}
|
|
||||||
end = 1;
|
|
||||||
break;
|
|
||||||
// Print an unsigned integer in upper hex form
|
|
||||||
case 'X':
|
|
||||||
term_writeStr(term, "0X");
|
|
||||||
numPrinted += 2;
|
|
||||||
switch (lng) {
|
|
||||||
case 0: {
|
|
||||||
unsigned int x;
|
|
||||||
x = va_arg(args, unsigned int);
|
|
||||||
numPrinted += printNum(term, x, 16, BASE16);
|
|
||||||
break;
|
|
||||||
} case 1: {
|
|
||||||
unsigned long lx;
|
|
||||||
lx = va_arg(args, unsigned long);
|
|
||||||
numPrinted += printNum(term, lx, 16, BASE16);
|
|
||||||
break;
|
|
||||||
} default: {
|
|
||||||
unsigned long long llx;
|
|
||||||
llx = va_arg(args, unsigned long long);
|
|
||||||
numPrinted += printNum(term, llx, 16, BASE16);
|
|
||||||
break;
|
|
||||||
}}
|
|
||||||
end = 1;
|
|
||||||
break;
|
|
||||||
// Exit if we reach the end of the string
|
|
||||||
case '\0':
|
|
||||||
end = 1;
|
|
||||||
break;
|
|
||||||
// Unknown character; just print the character
|
|
||||||
default:
|
|
||||||
term_putChar(term, fmt[i]);
|
|
||||||
numPrinted++;
|
|
||||||
end = 1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
// Print the number
|
||||||
|
numPrinted += printNum(term, unum, 10, BASE16);
|
||||||
|
|
||||||
|
// If specified, print succeeding spaces
|
||||||
|
if ((mode >> 5) % 2 == 1) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = 0;
|
||||||
|
break;
|
||||||
|
// Print an unsigned integer
|
||||||
|
} case 'u': {
|
||||||
|
uintmax_t num;
|
||||||
|
|
||||||
|
// Pull the argument from the list
|
||||||
|
switch (length) {
|
||||||
|
case 1:
|
||||||
|
num = va_arg(args, unsigned long);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
num = va_arg(args, unsigned long long);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
num = va_arg(args, size_t);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
num = va_arg(args, intmax_t);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
num = va_arg(args, ptrdiff_t);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
num = va_arg(args, unsigned int);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the length of the printed number
|
||||||
|
unsigned int len = numLen(num, 10);
|
||||||
|
|
||||||
|
// Get the length of the printed number with formatting
|
||||||
|
unsigned int flen = len;
|
||||||
|
if (precision > len)
|
||||||
|
flen += (precision - len);
|
||||||
|
if ((mode >> 3) % 2 == 1 || (mode >> 4) % 2 == 1)
|
||||||
|
flen++;
|
||||||
|
|
||||||
|
// If specified, print preceding space padding
|
||||||
|
if ((mode >> 5) % 2 == 0) {
|
||||||
|
if (precision > 0 || (mode >> 7) % 2 == 0) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If specified print the sign
|
||||||
|
if ((mode >> 3) % 2 == 1) {
|
||||||
|
term_putChar(term, '+');
|
||||||
|
numPrinted++;
|
||||||
|
} else if ((mode >> 4) % 2 == 1) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If specified, print the precision 0s
|
||||||
|
if (precision > 0) {
|
||||||
|
for (int j = precision - len; j > 0; j--) {
|
||||||
|
term_putChar(term, '0');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
} else if ((mode >> 7) % 2 == 1) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
|
term_putChar(term, '0');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the number
|
||||||
|
numPrinted += printNum(term, num, 10, BASE16);
|
||||||
|
|
||||||
|
// If specified, print succeeding spaces
|
||||||
|
if ((mode >> 5) % 2 == 1) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = 0;
|
||||||
|
break;
|
||||||
|
// Print an unsigned integer in hexadecimal
|
||||||
|
} case 'x':
|
||||||
|
case 'X': {
|
||||||
|
uintmax_t num;
|
||||||
|
|
||||||
|
// Pull the argument from the list
|
||||||
|
switch (length) {
|
||||||
|
case 1:
|
||||||
|
num = va_arg(args, unsigned long);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
num = va_arg(args, unsigned long long);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
num = va_arg(args, size_t);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
num = va_arg(args, intmax_t);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
num = va_arg(args, ptrdiff_t);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
num = va_arg(args, unsigned int);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the length of the printed number
|
||||||
|
unsigned int len = numLen(num, 10);
|
||||||
|
|
||||||
|
// Get the length of the printed number with formatting
|
||||||
|
unsigned int flen = len;
|
||||||
|
if (precision > len)
|
||||||
|
flen += (precision - len);
|
||||||
|
if ((mode >> 3) % 2 == 1 || (mode >> 4) % 2 == 1)
|
||||||
|
flen++;
|
||||||
|
if ((mode >> 6) % 2 == 1)
|
||||||
|
flen += 2;
|
||||||
|
|
||||||
|
// If specified, print preceding space padding
|
||||||
|
if ((mode >> 5) % 2 == 0) {
|
||||||
|
if (precision > 0 || (mode >> 7) % 2 == 0) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If specified print the sign
|
||||||
|
if ((mode >> 3) % 2 == 1) {
|
||||||
|
term_putChar(term, '+');
|
||||||
|
numPrinted++;
|
||||||
|
} else if ((mode >> 4) % 2 == 1) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If specified, print the 0x
|
||||||
|
if ((mode >> 6) % 2 == 1) {
|
||||||
|
term_putChar(term, '0');
|
||||||
|
if (fmt[i] == 'x')
|
||||||
|
term_putChar(term, 'x');
|
||||||
|
else
|
||||||
|
term_putChar(term, 'X');
|
||||||
|
numPrinted += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If specified, print the precision 0s
|
||||||
|
if (precision > 0) {
|
||||||
|
for (int j = precision - len; j > 0; j--) {
|
||||||
|
term_putChar(term, '0');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
} else if ((mode >> 7) % 2 == 1) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
|
term_putChar(term, '0');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the number
|
||||||
|
if (fmt[i] == 'x')
|
||||||
|
numPrinted += printNum(term, num, 16, BASE16L);
|
||||||
|
else
|
||||||
|
numPrinted += printNum(term, num, 16, BASE16);
|
||||||
|
|
||||||
|
// If specified, print succeeding spaces
|
||||||
|
if ((mode >> 5) % 2 == 1) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = 0;
|
||||||
|
break;
|
||||||
|
// Print an unsigned integer in octal
|
||||||
|
} case 'o': {
|
||||||
|
uintmax_t num;
|
||||||
|
|
||||||
|
// Pull the argument from the list
|
||||||
|
switch (length) {
|
||||||
|
case 1:
|
||||||
|
num = va_arg(args, unsigned long);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
num = va_arg(args, unsigned long long);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
num = va_arg(args, size_t);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
num = va_arg(args, intmax_t);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
num = va_arg(args, ptrdiff_t);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
num = va_arg(args, unsigned int);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the length of the printed number
|
||||||
|
unsigned int len = numLen(num, 10);
|
||||||
|
|
||||||
|
// Get the length of the printed number with formatting
|
||||||
|
unsigned int flen = len;
|
||||||
|
if (precision > len)
|
||||||
|
flen += (precision - len);
|
||||||
|
if ((mode >> 3) % 2 == 1 || (mode >> 4) % 2 == 1)
|
||||||
|
flen++;
|
||||||
|
if ((mode >> 6) % 2 == 1)
|
||||||
|
flen++;
|
||||||
|
|
||||||
|
// If specified, print preceding space padding
|
||||||
|
if ((mode >> 5) % 2 == 0) {
|
||||||
|
if (precision > 0 || (mode >> 7) % 2 == 0) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If specified print the sign
|
||||||
|
if ((mode >> 3) % 2 == 1) {
|
||||||
|
term_putChar(term, '+');
|
||||||
|
numPrinted++;
|
||||||
|
} else if ((mode >> 4) % 2 == 1) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If specified, print the 0x
|
||||||
|
if ((mode >> 6) % 2 == 1) {
|
||||||
|
term_putChar(term, '0');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If specified, print the precision 0s
|
||||||
|
if (precision > 0) {
|
||||||
|
for (int j = precision - len; j > 0; j--) {
|
||||||
|
term_putChar(term, '0');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
} else if ((mode >> 7) % 2 == 1) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
|
term_putChar(term, '0');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the number
|
||||||
|
numPrinted += printNum(term, num, 8, BASE16);
|
||||||
|
|
||||||
|
// If specified, print succeeding spaces
|
||||||
|
if ((mode >> 5) % 2 == 1) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = 0;
|
||||||
|
break;
|
||||||
|
// Print a string
|
||||||
|
} case 's': {
|
||||||
|
char *s = va_arg(args, char *);
|
||||||
|
term_writeStr(term, s);
|
||||||
|
numPrinted += strlen(s);
|
||||||
|
mode = 0;
|
||||||
|
break;
|
||||||
|
// Print a character
|
||||||
|
} case 'c':
|
||||||
|
if (mode % 2 == 0)
|
||||||
|
term_putChar(term, 'c');
|
||||||
|
else
|
||||||
|
term_putChar(term, (char) va_arg(args, int));
|
||||||
|
|
||||||
|
numPrinted++;
|
||||||
|
mode = 0;
|
||||||
|
break;
|
||||||
|
// Print a pointer
|
||||||
|
case 'p': {
|
||||||
|
uintmax_t num = va_arg(args, void *);
|
||||||
|
|
||||||
|
// Get the length of the printed number
|
||||||
|
unsigned int len = numLen(num, 16);
|
||||||
|
unsigned int flen = len + 2;
|
||||||
|
precision = sizeof(void *) * 2; // A byte is 2 hex chars
|
||||||
|
|
||||||
|
// If specified, print preceding space padding
|
||||||
|
if ((mode >> 5) % 2 == 0) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
term_putChar(term, '0');
|
||||||
|
term_putChar(term, 'x');
|
||||||
|
numPrinted += 2;
|
||||||
|
|
||||||
|
// If specified, print the precision 0s
|
||||||
|
for (int j = precision - len; j > 0; j--) {
|
||||||
|
term_putChar(term, '0');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the number
|
||||||
|
numPrinted += printNum(term, num, 16, BASE16);
|
||||||
|
|
||||||
|
// If specified, print succeeding spaces
|
||||||
|
if ((mode >> 5) % 2 == 1) {
|
||||||
|
for (int j = width - flen; j > 0; j--) {
|
||||||
|
term_putChar(term, ' ');
|
||||||
|
numPrinted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = 0;
|
||||||
|
break;
|
||||||
|
} default:
|
||||||
term_putChar(term, fmt[i]);
|
term_putChar(term, fmt[i]);
|
||||||
numPrinted++;
|
numPrinted++;
|
||||||
i++;
|
mode = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
lib/string.c
12
lib/string.c
@ -2,18 +2,6 @@
|
|||||||
|
|
||||||
#include <brados/string.h>
|
#include <brados/string.h>
|
||||||
|
|
||||||
// Find the first instance of c in str
|
|
||||||
// Returns -1 if c is not found
|
|
||||||
int strindexof(char c, const char *str)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < strlen(str); i++) {
|
|
||||||
if (str[i] == c)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the length of a string
|
// Find the length of a string
|
||||||
size_t strlen(const char *str)
|
size_t strlen(const char *str)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user