111 lines
2.4 KiB
C
111 lines
2.4 KiB
C
//----------------------------------------------------------------------------//
|
|
// OS on Kaleid //
|
|
// //
|
|
// Authors: spectral` //
|
|
// NeoX //
|
|
// //
|
|
// Desc: Conversion utilities - itoa family //
|
|
//----------------------------------------------------------------------------//
|
|
|
|
#include <libc.h>
|
|
|
|
// Digits table for bases <=36 (unused)
|
|
#if 0
|
|
static const char digits[] =
|
|
"0123456789abcdefghijklmnopqrstuvwxyz";
|
|
#endif
|
|
|
|
//
|
|
// Integer to string in any base between 2 and 36 (included)
|
|
// Returns str
|
|
//
|
|
#if defined(_NEED_ITOA)
|
|
|
|
#define _IL_MIN INT_MIN
|
|
#define _IL_MIN_STRING "-2147483648"
|
|
char *itoa(int i, char *str, int base)
|
|
{
|
|
int rem;
|
|
|
|
#elif defined(_NEED_LTOA)
|
|
|
|
#define _IL_MIN LONG_MIN
|
|
#define _IL_MIN_STRING "-9223372036854775808"
|
|
char *ltoa(long i, char *str, int base)
|
|
{
|
|
long rem;
|
|
|
|
#elif defined(_NEED_UTOA)
|
|
|
|
char *utoa(uint i, char *str, int base)
|
|
{
|
|
uint rem;
|
|
|
|
#elif defined(_NEED_ULTOA)
|
|
|
|
char *ultoa(ulong i, char *str, int base)
|
|
{
|
|
ulong rem;
|
|
|
|
#else
|
|
#error "What am I supposed to declare?"
|
|
#endif
|
|
char *orig = str;
|
|
|
|
#if defined(_NEED_ITOA) || defined(_NEED_LTOA)
|
|
// Deal with negatives
|
|
int neg = 0;
|
|
if (i < 0 && base == 10) {
|
|
|
|
// Handle INT_MIN and LONG_MIN...
|
|
if (__builtin_expect(i == _IL_MIN, 0)) {
|
|
strcpy(orig, _IL_MIN_STRING);
|
|
goto leave;
|
|
}
|
|
|
|
else {
|
|
neg = 1;
|
|
i = -i;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// Only handle base 2 -> 36
|
|
if (base < 2 || base > 36) {
|
|
seterrno(EINVAL);
|
|
*orig = '\0';
|
|
goto leave;
|
|
}
|
|
|
|
// Deal with zero separately
|
|
if (i == 0) {
|
|
*str++ = '0';
|
|
*str = '\0';
|
|
goto leave;
|
|
}
|
|
|
|
// Compute digits... in reverse order
|
|
while (i > 0) {
|
|
rem = i % base;
|
|
*str++ = (rem > 9)
|
|
? (rem - 10) + 'a'
|
|
: rem + '0';
|
|
i /= base;
|
|
}
|
|
|
|
#if defined(_NEED_ITOA) || defined(_NEED_LTOA)
|
|
if (neg) *str++ = '-';
|
|
#endif
|
|
|
|
*str = '\0';
|
|
|
|
// Reverse the string
|
|
orig = strrev2(orig);
|
|
|
|
// End of conversion
|
|
leave:
|
|
return orig;
|
|
}
|
|
|
|
|