2010-08-08 10:06:34 +02:00
|
|
|
#include "base36.h"
|
|
|
|
|
2021-02-14 18:51:57 +01:00
|
|
|
#include <assert.h>
|
2021-02-14 20:47:12 +01:00
|
|
|
#include <stdio.h>
|
2010-08-08 10:06:34 +02:00
|
|
|
#include <stdlib.h>
|
2019-07-28 12:56:59 +02:00
|
|
|
#include <string.h>
|
2010-08-08 10:06:34 +02:00
|
|
|
#include <ctype.h>
|
|
|
|
|
2019-07-28 12:56:59 +02:00
|
|
|
#define USE_STRTOL
|
|
|
|
#ifdef USE_STRTOL
|
|
|
|
int atoi36(const char *str)
|
|
|
|
{
|
|
|
|
assert(str);
|
|
|
|
return (int)strtol(str, NULL, 36);
|
|
|
|
}
|
|
|
|
#else
|
2011-03-07 08:02:35 +01:00
|
|
|
int atoi36(const char *str)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2014-08-23 09:17:58 +02:00
|
|
|
const unsigned char *s = (const unsigned char *)str;
|
|
|
|
int i = 0, sign = 1;
|
|
|
|
assert(s);
|
|
|
|
if (!(*s))
|
|
|
|
return 0;
|
|
|
|
if (*s == '-') {
|
|
|
|
sign = -1;
|
|
|
|
++s;
|
|
|
|
}
|
|
|
|
while (isalnum(*(unsigned char *)s)) {
|
2018-12-15 18:14:36 +01:00
|
|
|
if (islower(*s))
|
2014-08-23 09:17:58 +02:00
|
|
|
i = i * 36 + (*s) - 'a' + 10;
|
2017-02-03 21:19:39 +01:00
|
|
|
else if (isdigit(*s))
|
2014-08-23 09:17:58 +02:00
|
|
|
i = i * 36 + (*s) - '0';
|
2018-12-15 18:14:36 +01:00
|
|
|
else if (isupper(*(unsigned char *)s))
|
|
|
|
i = i * 36 + (*s) - 'A' + 10;
|
2014-08-23 09:17:58 +02:00
|
|
|
else
|
|
|
|
break;
|
|
|
|
++s;
|
|
|
|
}
|
|
|
|
if (i < 0)
|
|
|
|
return 0;
|
|
|
|
return i * sign;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
2019-07-28 12:56:59 +02:00
|
|
|
#endif
|
2010-08-08 10:06:34 +02:00
|
|
|
|
2017-12-11 18:20:21 +01:00
|
|
|
const char *itoab_r(int i, int base, char *s, size_t len)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2017-12-11 18:20:21 +01:00
|
|
|
char *dst;
|
2010-08-08 10:06:34 +02:00
|
|
|
|
2017-12-11 18:20:21 +01:00
|
|
|
assert(len > 2);
|
|
|
|
dst = s + len - 2;
|
2018-02-25 19:17:20 +01:00
|
|
|
dst[1] = 0;
|
2014-08-23 09:17:58 +02:00
|
|
|
if (i != 0) {
|
2017-12-08 19:59:49 +01:00
|
|
|
int neg = 0;
|
|
|
|
|
2014-08-23 09:17:58 +02:00
|
|
|
if (i < 0) {
|
|
|
|
i = -i;
|
|
|
|
neg = 1;
|
|
|
|
}
|
2015-01-30 20:37:14 +01:00
|
|
|
while (i && dst >= s) {
|
2014-08-23 09:17:58 +02:00
|
|
|
int x = i % base;
|
|
|
|
i = i / base;
|
2014-09-29 18:32:12 +02:00
|
|
|
if (x < 10) {
|
2014-08-23 09:17:58 +02:00
|
|
|
*(dst--) = (char)('0' + x);
|
2014-09-29 18:32:12 +02:00
|
|
|
}
|
|
|
|
else if ('a' + x - 10 == 'l') {
|
2014-08-23 09:17:58 +02:00
|
|
|
*(dst--) = 'L';
|
2015-01-30 20:37:14 +01:00
|
|
|
}
|
2014-09-29 18:32:12 +02:00
|
|
|
else {
|
2014-08-23 09:17:58 +02:00
|
|
|
*(dst--) = (char)('a' + (x - 10));
|
2014-09-29 18:32:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (dst > s) {
|
|
|
|
if (neg) {
|
|
|
|
*(dst) = '-';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
++dst;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2021-02-14 20:47:12 +01:00
|
|
|
fprintf(stderr, "static buffer exhausted, itoab(%d, %d)", i, base);
|
2014-09-29 18:32:12 +02:00
|
|
|
assert(i == 0 || !"itoab: static buffer exhausted");
|
2014-08-23 09:17:58 +02:00
|
|
|
}
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
2018-02-25 19:17:20 +01:00
|
|
|
else {
|
|
|
|
dst[0] = '0';
|
|
|
|
}
|
2010-08-08 10:06:34 +02:00
|
|
|
|
2014-08-23 09:17:58 +02:00
|
|
|
return dst;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2018-02-25 19:17:20 +01:00
|
|
|
const char *itoa36_r(int i, char *result, size_t len)
|
|
|
|
{
|
|
|
|
return itoab_r(i, 36, result, len);
|
|
|
|
}
|
2018-02-25 20:49:33 +01:00
|
|
|
|
2017-12-11 18:20:21 +01:00
|
|
|
const char *itoab(int i, int base)
|
|
|
|
{
|
|
|
|
static char sstr[80];
|
|
|
|
char *s;
|
|
|
|
static int index = 0; /* STATIC_XCALL: used across calls */
|
|
|
|
|
|
|
|
s = sstr + (index * 20);
|
|
|
|
index = (index + 1) & 3; /* quick for % 4 */
|
|
|
|
|
|
|
|
return itoab_r(i, base, s, 20);
|
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
const char *itoa36(int i)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2014-08-23 09:17:58 +02:00
|
|
|
return itoab(i, 36);
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
const char *itoa10(int i)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2014-08-23 09:17:58 +02:00
|
|
|
return itoab(i, 10);
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|