feat: modification de la fonction printf

This commit is contained in:
Nicolas Hordé 2018-08-29 10:12:00 +02:00
parent e3c09a2191
commit ca1f1c18a8
4 changed files with 210 additions and 67 deletions

View File

@ -4,3 +4,5 @@ u32 abs(int x);
random(u32 lower, u32 upper); random(u32 lower, u32 upper);
u32 rand(); u32 rand();
void randomize(); void randomize();
u8 log2(u32 n);
u8 log10(u32 n);

View File

@ -13,7 +13,9 @@ typedef struct console {
void showhex(u8 src); void showhex(u8 src);
void putchar(u8 thechar); void putchar(u8 thechar);
void print(u8* string); u32 print(u8* string);
void printf (const u8 *string, ...); u32 printf (const u8 *string, ...);
void changevc(u8 vc); void changevc(u8 vc);
u8* itoa(u32 num, u8* str, u8 base, u8 achar);
u8* sitoa(int num, u8* str);

View File

@ -1,6 +1,33 @@
#include "types.h" #include "types.h"
#include "timer.h" #include "timer.h"
/******************************************************************************/
/* Fonction qui retourne le logarithme 2 */
u8 log2(u32 n) {
if (n==0) return 0;
int logValue = -1;
while (n) {
logValue++;
n >>= 1;
}
return logValue;
}
/******************************************************************************/
/* Fonction qui retourne le logarithme 10 */
u8 log10(u32 n)
{
return (n >= 1000000000u) ? 9 : (n >= 100000000u) ? 8 :
(n >= 10000000u) ? 7 : (n >= 1000000u) ? 6 :
(n >= 100000u) ? 5 : (n >= 10000u) ? 4 :
(n >= 1000u) ? 3 : (n >= 100u) ? 2 : (n >= 10u) ? 1u : 0u;
}
/******************************************************************************/ /******************************************************************************/
/* Fonction qui retourne la valeur absolue */ /* Fonction qui retourne la valeur absolue */

View File

@ -288,96 +288,208 @@ void putchar(u8 thechar)
/* affiche une chaine de caractère a l'écran */ /* affiche une chaine de caractère a l'écran */
void print(u8 * string) u32 print(u8 * string)
{ {
u8 *source; u8 *source;
u32 i=0;
source = string; source = string;
while (*source != 0) { while (*source != 0) {
putchar(*source++); putchar(*source++);
i++;
} }
return i;
} }
/*******************************************************************************/ /*******************************************************************************/
# define buffersize 1024
/* affiche une chaine de caractère formaté a l'ecran */ /* affiche une chaine de caractère formaté a l'ecran */
void printf(const u8 * string, ...) u32 printf(const u8 *string, ...)
{ {
va_list ap; va_list args;
u8 buffer[50]; u8 achar,temp;
u8 *pointer; u32 sizes[]={0xFF,0xFFFF,0xFFFFFFFF};
u8 asize,charadd;
u8 strbase2 = "b\000";
u8 strbase8 = "o\000";
u8 strbase16 = "h\000";
u8 hexadecimal[]="*0x\000";
u8 buffer[buffersize];
u8 *str = string;
u8 *strtemp;
u32 i = 0, counter = 0;
u32 num;
bool flag=false;
u8 radix; va_start(args, string);
bool signe; for (achar = *str; achar != '\000'; i++, achar = *(str + i))
long num; {
if (achar != '%' && !flag)
va_start(ap, string); {
while (*string != 0) { putchar(achar);
if (*string != '%') counter++;
putchar(*string); asize=2;
else { charadd=0;
switch (*++string) { }
else if (achar == '%' || flag)
{
++i;
achar = *(str + i);
switch(achar)
{
case '0':
charadd='0';
flag=true;
case ' ':
charadd=' ';
flag=true;
case 'h':
asize--;
flag=true;
case 'l':
asize++;
flag=true;
case 'u':
num = (u32)va_arg(args, int);
num&=sizes[asize];
itoa(num, buffer, 10, charadd);
counter += print(buffer);
flag=false;
break;
case 'o':
num = (u32)va_arg(args, int);
num&=sizes[asize];
itoa(num, buffer, 8, charadd);
counter += print(buffer)+1;
print(strbase8);
flag=false;
break;
case 'c': case 'c':
putchar(va_arg(ap, int)); temp = (u8)va_arg(args, int);
putchar(temp);
counter++;
flag=false;
break; break;
case 'u':
radix = 10;
signe = 0;
showstring:
num = va_arg(ap, int);
pointer = buffer + 50 - 1;
*pointer = '\0';
if ((signe == 1) && (num < 0)) {
num = -num;
signe++;
}
do {
unsigned long temp;
temp = (unsigned long)num % radix;
pointer--;
if (temp < 10)
*pointer = temp + '0';
else
*pointer = temp - 10 + 'a';
num = (unsigned long)num / radix;
}
while (num != 0);
if (signe > 1)
*(--pointer) = '-';
while (*pointer != 0)
putchar(*pointer++);
break;
case 'o':
radix = 8;
signe = 0;
goto showstring;
case 'd': case 'd':
case 'i': case 'i':
radix = 10; num = (int)va_arg(args, int);
signe = 1; num&=sizes[asize];
goto showstring; sitoa(num, buffer);
case 'x': counter += print(buffer);
radix = 16; flag=false;
signe = 0;
goto showstring;
case 's':
pointer = va_arg(ap, u8 *);
if (!pointer)
pointer = "(null)";
while (*pointer != 0)
putchar(*pointer++);
break; break;
case '%': case 's':
putchar('%'); strtemp = (u8 *)va_arg(args, u8 *);
counter += print(strtemp);
flag=false;
break;
case 'p':
num = (u32)va_arg(args, int);
num&=sizes[asize];
print(hexadecimal);
itoa(num, buffer, 16, '0');
counter += print(buffer)+2;
flag=false;
break;
case 'x':
case 'X':
num = (u32)va_arg(args, int);
num&=sizes[asize];
itoa(num, buffer, 16, charadd);
counter += print(buffer)+1;
if (achar=='X')
strtoupper(buffer);
print(strbase16);
flag=false;
break;
case 'b':
num = (u32)va_arg(args, int);
num&=sizes[asize];
itoa(num, buffer, 2, charadd);
counter += print(buffer)+1;
print(strbase2);
flag=false;
break; break;
default: default:
putchar(va_arg(ap, int));
break; break;
} }
} }
string++;
} }
va_end(ap); va_end(args);
return counter;
} }
/*******************************************************************************/ /*******************************************************************************/
/* converti un entier non signé en chaine de caractère */
u8* itoa(u32 num, u8* str, u8 base, u8 achar)
{
u32 pointer = 0, i=0, size=0;
if (num == 0)
{
str[pointer++] = '0';
str[pointer] = '\0';
return str;
}
switch (base)
{
case 2:
size=log2(num);
break;
case 8:
size=log2(num)/4;
break;
case 10:
size=log10(num);
break;
case 16:
size=log2(num)/2;
break;
}
for(i=0;i<size;size++)
{
u32 result = num % (u32)base;
str[pointer++] = (result > 9)? (result-10) + 'a' : result + '0';
num = num / (u32)base;
if ((num==0) && (achar==0))
break;
}
str[pointer] = '\0';
strinvert(str);
return str;
}
/*******************************************************************************/
/* converti un entier en chaine de caractère */
u8* sitoa(int num, u8* str)
{
u32 i = 0;
bool isNegative = false;
if (num == 0)
{
str[i++] = '0';
str[i] = '\0';
return str;
}
if (num < 0)
{
isNegative = true;
num = -num;
}
while (num != 0)
{
u32 result = num % 10;
str[i++] = (result > 9)? (result-10) + 'a' : result + '0';
num = num/ 10;
}
if (isNegative)
str[i++] = '-';
str[i] = '\0';
strinvert(str);
return str;
}