Half implemented printf (doesn't compile)
This commit is contained in:
parent
326eb27ac9
commit
110df5047d
@ -15,26 +15,29 @@ 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, ...)
|
||||||
{
|
{
|
||||||
int *argp = (int*)&fmt;
|
int *argp = (int *)&fmt;
|
||||||
int state = PRINTF_STATE_NORMAL;
|
int state = PRINTF_STATE_NORMAL;
|
||||||
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,170 +46,204 @@ 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++;
|
||||||
|
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++;
|
argp++;
|
||||||
break;
|
}
|
||||||
case 's':
|
break;
|
||||||
puts(*(char **)argp);
|
|
||||||
argp++;
|
case '%':
|
||||||
break;
|
putc('%');
|
||||||
case '%':
|
break;
|
||||||
putc('%');
|
|
||||||
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 'p':
|
case 'x':
|
||||||
radix = 16;
|
case 'p':
|
||||||
sign = false;
|
radix = 16;
|
||||||
argp = printf_number(argp, length, sign, radix);
|
sign = false;
|
||||||
break;
|
argp = printf_number(argp, length, sign, radix);
|
||||||
case 'o':
|
break;
|
||||||
radix = 8;
|
|
||||||
sign = false;
|
case 'o':
|
||||||
argp = printf_number(argp, length, sign, radix);
|
radix = 8;
|
||||||
break;
|
sign = false;
|
||||||
//Se è messo un carattere non valido questo codice fa in modo che li ignora.
|
argp = printf_number(argp, length, sign, radix);
|
||||||
default:
|
break;
|
||||||
break;
|
|
||||||
|
// ignore invalid spec
|
||||||
|
default:
|
||||||
|
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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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];
|
char buffer[32];
|
||||||
unsigned long long number;
|
unsigned long long number;
|
||||||
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_LONG:
|
case PRINTF_LENGTH_DEFAULT:
|
||||||
if (sign)
|
if (sign)
|
||||||
|
{
|
||||||
|
int n = *argp;
|
||||||
|
if (n < 0)
|
||||||
{
|
{
|
||||||
long int n = *(long int*)argp;
|
n = -n;
|
||||||
if (n < 0)
|
number_sign = -1;
|
||||||
{
|
|
||||||
n = -n;
|
|
||||||
number_sign = -1;
|
|
||||||
}
|
|
||||||
number = (unsigned long long)n;
|
|
||||||
}
|
}
|
||||||
else
|
number = (unsigned long long)n;
|
||||||
{
|
}
|
||||||
number = (*unsigned long int*)argp;
|
else
|
||||||
}
|
{
|
||||||
argp += 2;
|
number = *(unsigned int *)argp;
|
||||||
break;
|
}
|
||||||
case PRINTF_LENGTH_LONG_LONG:
|
argp++;
|
||||||
if (sign)
|
break;
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
case PRINTF_LENGTH_LONG:
|
||||||
|
if (sign)
|
||||||
|
{
|
||||||
|
long int n = *(long int *)argp;
|
||||||
|
if (n < 0)
|
||||||
|
{
|
||||||
|
n = -n;
|
||||||
|
number_sign = -1;
|
||||||
}
|
}
|
||||||
argp++;
|
number = (unsigned long long)n;
|
||||||
break;
|
}
|
||||||
|
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
|
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;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user