Half implemented printf (doesn't compile)

This commit is contained in:
Vincenzo Aleksey Brocato 2024-08-02 19:28:04 +02:00 committed by VinceAle7082
parent 326eb27ac9
commit 110df5047d

View File

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