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