summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Mannens <jake72360@gmail.com>2018-06-18 01:55:57 +1000
committerJake Mannens <jake72360@gmail.com>2018-06-18 01:55:57 +1000
commit627d2d0c0ee5147f53fdba8fc1f9108f8edeb8f3 (patch)
tree5841b06d120ce9d60a7439235ba989970e7d52c7
parentaa289699cd65e59bd107fc9827995e39bf98e2d0 (diff)
Added interpretation of the '%' conversion specifier which acts as an
escape sequence printing a literal '%'. Added the 'X' conversion specifier which differs from the 'x' specifier in that resulting letters are converted to uppercase. Added interpretation of the '#' alt flag which now causes the '0x' prefix to be added to every hex conversion.
-rw-r--r--kernel/kmain.c5
-rw-r--r--kernel/vsprintf.c60
2 files changed, 46 insertions, 19 deletions
diff --git a/kernel/kmain.c b/kernel/kmain.c
index 793ca17..e31782c 100644
--- a/kernel/kmain.c
+++ b/kernel/kmain.c
@@ -8,5 +8,8 @@ void kmain(void) {
printf("Kernel booting...\n");
printf("Kernel booted!\n");
- printf("Number: %04x\n", 0x18C);
+ printf("Number: %s %04x\n", "test", 0x18C);
+ printf("Number: %s %04X\n", "test", 0x18C);
+ printf("Number: %s %#04x\n", "test", 0x18C);
+ printf("Number: %s %#04X\n", "test", 0x18C);
}
diff --git a/kernel/vsprintf.c b/kernel/vsprintf.c
index 93a2ada..4fdb2c4 100644
--- a/kernel/vsprintf.c
+++ b/kernel/vsprintf.c
@@ -2,23 +2,35 @@
#include <stdint.h>
enum TYPE {
- TYPE_INT = 1,
- TYPE_UINT = 2,
- TYPE_HEX = 3,
- TYPE_STRING = 4
+ TYPE_INT = 1,
+ TYPE_UINT = 2,
+ TYPE_HEX = 3,
+ TYPE_STRING = 4,
+ TYPE_PERCENT = 5
};
enum FLAGS {
FL_ZERO = 1, /* zero padded */
+ FL_ALT = 2, /* alternate form (effect is type dependent) */
+ FL_UPPER = 4 /* uppercase */
};
static void hex(char **str, char flags, int fwidth, int size, int x) {
int i, y, len;
char c;
- char *s = "0x";
+ char *prefl = "0x";
+ char *prefu = "0X";
- while(*s)
- *(*str)++ = *s++;
+ /* print the prefix, if the alt flag is set */
+ if(flags & FL_ALT) {
+ if(flags & FL_UPPER) {
+ while(*prefu)
+ *(*str)++ = *prefu++;
+ } else {
+ while(*prefl)
+ *(*str)++ = *prefl++;
+ }
+ }
/* calculate the number of digits */
len = 0;
@@ -40,8 +52,11 @@ static void hex(char **str, char flags, int fwidth, int size, int x) {
/* actually print the digits */
for(i = 0; i < sizeof(x) << 1; i++) {
c = ((unsigned int) x >> 28) + '0';
- if(c > '9')
- c += 7;
+ if(c > '9') {
+ c += 0x27;
+ if(flags & FL_UPPER)
+ c -= 0x20;
+ }
if(c != '0')
*(*str)++ = c;
@@ -70,37 +85,43 @@ int vsprintf(char *str, char *fmt, va_list ap) {
fmt++;
while(1) {
switch(*fmt) {
+ case '#':
+ flags |= FL_ALT;
+ break;
+ case '%':
+ type = TYPE_PERCENT;
+ goto done;
case 's':
- if(type)
- goto done;
type = TYPE_STRING;
- break;
+ goto done;
case 'x':
- if(type)
- goto done;
type = TYPE_HEX;
- break;
+ goto done;
+ case 'X':
+ type = TYPE_HEX;
+ flags |= FL_UPPER;
+ goto done;
default:
/* the first zero enables zero-padding */
if(*fmt == '0' && !fwidth) {
flags |= FL_ZERO;
- goto next;;
+ goto next;
}
/* subsequent numbers indicate field width */
if(*fmt >= '0' && *fmt <= '9') {
fwidth = (fwidth * 10) + (*fmt - '0');
- goto next;;
+ goto next;
}
goto done;
- break;
}
next:
fmt++;
}
done:
+ fmt++;
switch(type) {
case TYPE_STRING:
@@ -112,6 +133,9 @@ done:
x = va_arg(ap, int);
hex(&str, flags, fwidth, 4, x);
break;
+ case TYPE_PERCENT:
+ *str++ = '%';
+ break;
}
}