补全printf的整型支持
This commit is contained in:
parent
a389dcf93a
commit
db97135880
@ -6,18 +6,20 @@
|
||||
#include "tty.h"
|
||||
#include "serialport.h"
|
||||
|
||||
static void serialputch(int ch, void *cnt)
|
||||
static void serialputch(int ch, int *cnt)
|
||||
{
|
||||
// write_serial(ch);
|
||||
char _ch = ch;
|
||||
tty_write(cur_ntty, &_ch, 1);
|
||||
(*cnt)++;
|
||||
}
|
||||
|
||||
int vkprintf(const char *fmt, va_list ap)
|
||||
{
|
||||
|
||||
// vprintfmt((void*)kprintfputch, NULL, fmt, ap);
|
||||
vprintfmt((void *)serialputch, NULL, fmt, ap);
|
||||
int cnt = 0;
|
||||
vprintfmt((void *)serialputch, &cnt, fmt, ap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -24,17 +24,39 @@ printnum(void (*putch)(int, void*), void *putdat,
|
||||
putch("0123456789abcdef"[num % base], putdat);
|
||||
}
|
||||
|
||||
static void
|
||||
printnumupper(void (*putch)(int, void*), void *putdat,
|
||||
unsigned long num, unsigned base, int width, int padc)
|
||||
{
|
||||
// first recursively print all preceding (more significant) digits
|
||||
if (num >= base) {
|
||||
printnumupper(putch, putdat, num / base, base, width - 1, padc);
|
||||
} else {
|
||||
// print any needed pad characters before first digit
|
||||
while (--width > 0)
|
||||
putch(padc, putdat);
|
||||
}
|
||||
|
||||
// then print this (the least significant) digit
|
||||
putch("0123456789ABCDEF"[num % base], putdat);
|
||||
}
|
||||
|
||||
// Get an unsigned int of various possible sizes from a varargs list,
|
||||
// depending on the lflag parameter.
|
||||
static unsigned long long
|
||||
getuint(va_list *ap, int lflag)
|
||||
{
|
||||
if (lflag >= 2)
|
||||
switch (lflag)
|
||||
{
|
||||
case 2:
|
||||
return va_arg(*ap, unsigned long long);
|
||||
else if (lflag)
|
||||
case 1:
|
||||
return va_arg(*ap, unsigned long);
|
||||
else
|
||||
case 0:
|
||||
return va_arg(*ap, unsigned int);
|
||||
default:
|
||||
return va_arg(*ap, unsigned int);
|
||||
}
|
||||
}
|
||||
|
||||
// Same as getuint but signed - can't use getuint
|
||||
@ -42,12 +64,17 @@ getuint(va_list *ap, int lflag)
|
||||
static long long
|
||||
getint(va_list *ap, int lflag)
|
||||
{
|
||||
if (lflag >= 2)
|
||||
switch (lflag)
|
||||
{
|
||||
case 2:
|
||||
return va_arg(*ap, long long);
|
||||
else if (lflag)
|
||||
case 1:
|
||||
return va_arg(*ap, long);
|
||||
else
|
||||
case 0:
|
||||
return va_arg(*ap, int);
|
||||
default:
|
||||
return va_arg(*ap, int);
|
||||
}
|
||||
}
|
||||
|
||||
// Main function to format and print a string.
|
||||
@ -128,7 +155,10 @@ vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap)
|
||||
case 'l':
|
||||
lflag++;
|
||||
goto reswitch;
|
||||
|
||||
// short flag, though auto promotion will be executed
|
||||
case 'h':
|
||||
lflag--;
|
||||
goto reswitch;
|
||||
// character
|
||||
case 'c':
|
||||
putch(va_arg(ap, int), putdat);
|
||||
@ -151,7 +181,7 @@ vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap)
|
||||
break;
|
||||
|
||||
// (signed) decimal
|
||||
case 'd':
|
||||
case 'd': case 'i':
|
||||
num = getint(&ap, lflag);
|
||||
if ((long long) num < 0) {
|
||||
putch('-', putdat);
|
||||
@ -169,11 +199,16 @@ vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap)
|
||||
// (unsigned) octal
|
||||
case 'o':
|
||||
// Replace this with your code.
|
||||
putch('X', putdat);
|
||||
putch('X', putdat);
|
||||
putch('X', putdat);
|
||||
num = getuint(&ap, lflag);
|
||||
base = 8;
|
||||
goto number;
|
||||
break;
|
||||
// binary, non-standard ext
|
||||
case 'b':
|
||||
num = getuint(&ap, lflag);
|
||||
base = 2;
|
||||
goto number;
|
||||
break;
|
||||
|
||||
// pointer
|
||||
case 'p':
|
||||
putch('0', putdat);
|
||||
@ -182,7 +217,11 @@ vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap)
|
||||
(uintptr_t) va_arg(ap, void *);
|
||||
base = 16;
|
||||
goto number;
|
||||
|
||||
case 'X':
|
||||
num = getuint(&ap, lflag);
|
||||
base = 16;
|
||||
printnumupper(putch, putdat, num, base, width, padc);
|
||||
break;
|
||||
// (unsigned) hexadecimal
|
||||
case 'x':
|
||||
num = getuint(&ap, lflag);
|
||||
@ -190,7 +229,11 @@ vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap)
|
||||
number:
|
||||
printnum(putch, putdat, num, base, width, padc);
|
||||
break;
|
||||
|
||||
case 'n': {
|
||||
int * nptr = (int *)va_arg(ap, void *);
|
||||
*nptr = *(int*)putdat;
|
||||
break;
|
||||
}
|
||||
// escaped '%' character
|
||||
case '%':
|
||||
putch(ch, putdat);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user