Half implemented printf (doesn't compile)

This commit is contained in:
Vincenzo Aleksey Brocato 2024-08-02 19:28:04 +02:00
parent ff5848de97
commit 12874aade6

View File

@ -15,26 +15,29 @@ void puts(const char *str)
}
#define PRINTF_STATE_NORMAL 0
#define PRINTF_STATE_LENGHT 1
#define PRINTF_STATE_LENGHT_SHORT 2
#define PRINTF_STATE_LENGHT_LONG 1
#define PRINTF_STATE_LENGTH 1
#define PRINTF_STATE_LENGTH_SHORT 2
#define PRINTF_STATE_LENGTH_LONG 3
#define PRINTF_STATE_SPEC 4
#define PRINTF_LENGTH_DEFAULT 0
#define PRINTF_LENGTH_SHORT_SHORT 1
#define PRINTF_LENGTH_SHORT 2
#define PRINTF_LENGTH_LONG 3
#define PRINTF_LENGTH_LONG_LONG 4
int* printf_number(int *argp, int length, bool sign, int radix)
const char g_HexChars[] = '0123456789abcdef'
int * printf_number(int *argp, int length, bool sign, int radix);
void _cdecl printf(const char *fmt, ...)
{
int *argp = (int*)&fmt;
int *argp = (int *)&fmt;
int state = PRINTF_STATE_NORMAL;
int length = PRINTF_LENGTH_DEFAULT;
int radix = 10;
bool sign = false;
argp++;
while (*fmt)
{
switch (state)
@ -43,170 +46,204 @@ void _cdecl printf(const char *fmt, ...)
switch (*fmt)
{
case '%':
state = PRINTF_STATE_LENGHT;
state = PRINTF_STATE_LENGTH;
break;
default:
putc(*fmt);
break;
}
break;
case PRINTF_STATE_LENGHT:
case PRINTF_STATE_LENGTH:
switch (*fmt)
{
case 'h':
length = PRINTF_LENGTH_SHORT;
state = PRINTF_STATE_LENGHT_SHORT;
state = PRINTF_STATE_LENGTH_SHORT;
break;
case 'l':
length = PRINTF_LENGTH_LONG;
state = PRINTF_STATE_LENGHT_LONG;
state = PRINTF_STATE_LENGTH_LONG;
break;
default:
goto PRINTF_STATE_SPEC;
goto PRINTF_STATE_SPEC_;
}
break;
case PRINTF_LENGTH_SHORT:
case PRINTF_STATE_LENGTH_SHORT:
if (*fmt == 'h')
{
length = PRINTF_LENGTH_SHORT_SHORT;
state = PRINTF_STATE_SPEC;
}
else
goto PRINTF_STATE_SPEC_;
break;
case PRINTF_STATE_LENGTH_LONG:
if (*fmt == 'l')
{
goto PRINTF_STATE_SPEC;
length = PRINTF_LENGTH_LONG_LONG;
state = PRINTF_STATE_SPEC;
}
else
goto PRINTF_STATE_SPEC_;
break;
case PRINTF_STATE_SPEC:
PRINTF_STATE_SPEC_:
switch (*fmt)
{
case 'c':
putc((char)*argp);
case 'c':
putc((char)*argp);
argp++;
break;
case 's':
if (length == PRINTF_LENGTH_LONG || length == PRINTF_LENGTH_LONG_LONG)
{
puts_f(*(const char far **)argp);
argp += 2;
}
else
{
puts(*(const char **)argp);
argp++;
break;
case 's':
puts(*(char **)argp);
argp++;
break;
case '%':
putc('%');
break;
case 'd':
case 'i':
radix = 10;
sign = true;
argp = printf_number(argp, length, sign, radix);
break;
case 'u':
radix = 10;
sign = false;
argp = printf_number(argp, length, sign, radix);
break;
case 'x':
case 'X':
case 'p':
radix = 16;
sign = false;
argp = printf_number(argp, length, sign, radix);
break;
case 'o':
radix = 8;
sign = false;
argp = printf_number(argp, length, sign, radix);
break;
//Se è messo un carattere non valido questo codice fa in modo che li ignora.
default:
break;
}
break;
case '%':
putc('%');
break;
case 'd':
case 'i':
radix = 10;
sign = true;
argp = printf_number(argp, length, sign, radix);
break;
case 'u':
radix = 10;
sign = false;
argp = printf_number(argp, length, sign, radix);
break;
case 'X':
case 'x':
case 'p':
radix = 16;
sign = false;
argp = printf_number(argp, length, sign, radix);
break;
case 'o':
radix = 8;
sign = false;
argp = printf_number(argp, length, sign, radix);
break;
// ignore invalid spec
default:
break;
}
//Porta le variabili allo stato di default / normale.
// reset state
state = PRINTF_STATE_NORMAL;
length = PRINTF_LENGTH_DEFAULT;
radix = 10;
sign = false;
break;
}
fmt++;
}
}
int* printf_number(int* argp, int length, bool sign, int radix)
const char g_HexChars[] = "0123456789abcdef";
int *printf_number(int *argp, int length, bool sign, int radix)
{
char buffer[32];
unsigned long long number;
int number_sign = 1;
int pos = 0;
// process length
switch (length)
{
case PRINTF_LENGTH_SHORT_SHORT:
case PRINTF_LENGTH_SHORT:
case PRINTF_LENGTH_LONG:
if (sign)
case PRINTF_LENGTH_SHORT_SHORT:
case PRINTF_LENGTH_SHORT:
case PRINTF_LENGTH_DEFAULT:
if (sign)
{
int n = *argp;
if (n < 0)
{
long int n = *(long int*)argp;
if (n < 0)
{
n = -n;
number_sign = -1;
}
number = (unsigned long long)n;
n = -n;
number_sign = -1;
}
else
{
number = (*unsigned long int*)argp;
}
argp += 2;
break;
case PRINTF_LENGTH_LONG_LONG:
if (sign)
{
long long int n = *(long long int*)argp;
if (n < 0)
{
n = -n;
number_sign = -1;
}
number = (unsigned long long)n;
}
else
{
number = (*unsigned long long int *)argp;
}
argp += 4;
break;
case PRINTF_LENGTH_DEFAULT:
if (sign)
{
int n = *argp;
if (n < 0)
{
n = -n;
number_sign = -1;
}
number = n;
}
else
{
number = (*unsigned int*)argp;
number = (unsigned long long)n;
}
else
{
number = *(unsigned int *)argp;
}
argp++;
break;
case PRINTF_LENGTH_LONG:
if (sign)
{
long int n = *(long int *)argp;
if (n < 0)
{
n = -n;
number_sign = -1;
}
argp++;
break;
number = (unsigned long long)n;
}
else
{
number = *(unsigned long int *)argp;
}
argp += 2;
break;
case PRINTF_LENGTH_LONG_LONG:
if (sign)
{
long long int n = *(long long int *)argp;
if (n < 0)
{
n = -n;
number_sign = -1;
}
number = (unsigned long long)n;
}
else
{
number = *(unsigned long long int *)argp;
}
argp += 4;
break;
}
// convert number to ASCII
do
{
uint32_t rem = number % radix;
uint32_t rem;
x86_div64_32(number, radix, &number, &rem);
buffer[pos++] = g_HexChars[rem];
} while (number > 0);
// add sign
if (sign && number_sign < 0)
{
buffer[pos++] = '-';
}
// print number in reverse order
while (--pos >= 0)
putc(buffer[pos]);
return argp;
}