os-k/kaleid/common/itoa.c

126 lines
2.5 KiB
C
Raw Normal View History

2018-12-25 19:09:58 +01:00
//----------------------------------------------------------------------------//
// GNU GPL OS/K //
// //
// Authors: spectral` //
// NeoX //
// //
2019-01-02 17:19:13 +01:00
// Desc: Conversion utilities - itoa family //
2018-12-25 19:09:58 +01:00
//----------------------------------------------------------------------------//
2019-01-01 13:09:57 +01:00
#include <kaleid.h>
2018-12-25 19:09:58 +01:00
//
2019-01-19 22:36:38 +01:00
// Digits table for bases <=36 (unused)
2018-12-25 19:09:58 +01:00
//
2019-01-21 09:53:54 +01:00
#if 0
2019-01-14 14:31:49 +01:00
static const char digits[] =
"0123456789abcdefghijklmnopqrstuvwxyz";
2019-01-21 09:53:54 +01:00
#endif
2019-01-19 22:36:38 +01:00
2018-12-25 19:09:58 +01:00
//
2019-01-14 14:31:49 +01:00
// Integer to string in any base between 2 and 36 (included)
2018-12-25 19:09:58 +01:00
//
2019-01-19 22:36:38 +01:00
2019-01-01 17:37:58 +01:00
#if defined(_NEED_ITOA)
2019-01-19 22:36:38 +01:00
#define _IL_MIN INT_MIN
#define _IL_MIN_STRING "-2147483648"
2019-01-21 09:53:54 +01:00
char *itoa(int i, char *str, int base)
{
int rem;
2019-01-19 22:36:38 +01:00
2019-01-01 17:37:58 +01:00
#elif defined(_NEED_LTOA)
2019-01-19 22:36:38 +01:00
#define _IL_MIN LONG_MIN
#define _IL_MIN_STRING "-9223372036854775808"
2019-01-21 09:53:54 +01:00
char *ltoa(long i, char *str, int base)
{
long rem;
2019-01-19 22:36:38 +01:00
2019-01-01 17:37:58 +01:00
#elif defined(_NEED_UTOA)
2019-01-19 22:36:38 +01:00
2019-01-01 17:37:58 +01:00
char *utoa(uint i, char *str, int base)
2019-01-21 09:53:54 +01:00
{
uint rem;
2019-01-19 22:36:38 +01:00
2019-01-01 17:37:58 +01:00
#elif defined(_NEED_ULTOA)
2019-01-19 22:36:38 +01:00
2019-01-01 17:37:58 +01:00
char *ultoa(ulong i, char *str, int base)
2019-01-21 09:53:54 +01:00
{
ulong rem;
2019-01-19 22:36:38 +01:00
2019-01-01 17:37:58 +01:00
#else
2019-01-14 14:31:49 +01:00
#error "What am I supposed to declare?"
2019-01-01 17:37:58 +01:00
#endif
2018-12-25 19:09:58 +01:00
char *orig = str;
2019-01-01 17:37:58 +01:00
#if defined(_NEED_ITOA) || defined(_NEED_LTOA)
2019-01-14 14:31:49 +01:00
//
// Deal with negatives
//
2019-01-19 22:36:38 +01:00
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;
}
2018-12-25 19:09:58 +01:00
}
2019-01-01 17:37:58 +01:00
#endif
2019-01-14 14:31:49 +01:00
2019-01-19 22:36:38 +01:00
//
// Only handle base 2 -> 36
//
if (base < 2 || base > 36) {
__set_errno(EINVAL);
2019-01-21 09:53:54 +01:00
*orig = '\0';
2019-01-19 22:36:38 +01:00
goto leave;
}
2019-01-14 14:31:49 +01:00
//
// Deal with zero separately
//
2018-12-25 19:09:58 +01:00
if (i == 0) {
*str++ = '0';
2019-01-19 22:36:38 +01:00
*str = '\0';
goto leave;
2018-12-25 19:09:58 +01:00
}
2019-01-14 14:31:49 +01:00
//
// Compute digits... in reverse order
//
2018-12-25 19:09:58 +01:00
while (i > 0) {
2019-01-19 22:36:38 +01:00
rem = i % base;
*str++ = (rem > 9)
? (rem - 10) + 'a'
: rem + '0';
2018-12-25 19:09:58 +01:00
i /= base;
}
2019-01-01 17:37:58 +01:00
#if defined(_NEED_ITOA) || defined(_NEED_LTOA)
2018-12-25 19:09:58 +01:00
if (neg) *str++ = '-';
2019-01-01 17:37:58 +01:00
#endif
2018-12-25 19:09:58 +01:00
*str = '\0';
2019-01-14 14:31:49 +01:00
//
// Reverse the string
//
2019-01-19 22:36:38 +01:00
orig = strrev2(orig);
//
// End of conversion
//
leave:
return orig;
2018-12-25 19:09:58 +01:00
}