2020-12-07 04:46:37 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2020-11-30 11:40:33 +00:00
|
|
|
#include "config.h"
|
2020-12-07 04:46:37 +00:00
|
|
|
#endif
|
2020-11-30 11:40:33 +00:00
|
|
|
|
2022-01-24 02:15:39 +00:00
|
|
|
#include <kernaux/assert.h>
|
2022-01-19 10:35:02 +00:00
|
|
|
#include <kernaux/ntoa.h>
|
2022-01-18 07:39:28 +00:00
|
|
|
|
2022-01-24 01:59:16 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
|
2022-05-30 09:49:58 +00:00
|
|
|
char *kernaux_utoa(uint64_t value, char *buffer, int base, const char *prefix)
|
2022-01-18 07:39:28 +00:00
|
|
|
{
|
2022-06-13 16:28:00 +00:00
|
|
|
KERNAUX_ASSERT(buffer);
|
2022-01-24 16:52:12 +00:00
|
|
|
|
2022-05-30 23:53:18 +00:00
|
|
|
// Protect caller from invalid state in case of future assertions
|
|
|
|
*buffer = '\0';
|
|
|
|
|
2022-01-24 01:59:16 +00:00
|
|
|
switch (base) {
|
2022-01-24 02:32:11 +00:00
|
|
|
case 'b': case 'B': base = 2; break;
|
|
|
|
case 'o': case 'O': base = 8; break;
|
|
|
|
case 'd': case 'D': base = 10; break;
|
|
|
|
case 'h': case 'x': base = 16; break;
|
|
|
|
case 'H': case 'X': base = -16; break;
|
2022-01-24 02:10:23 +00:00
|
|
|
}
|
|
|
|
|
2022-01-24 02:32:11 +00:00
|
|
|
// Uppercase
|
2022-01-24 02:10:23 +00:00
|
|
|
char alpha = 'a';
|
|
|
|
if (base < 0) {
|
|
|
|
alpha = 'A';
|
|
|
|
base = -base;
|
2022-01-24 01:59:16 +00:00
|
|
|
}
|
|
|
|
|
2022-06-13 16:28:00 +00:00
|
|
|
KERNAUX_ASSERT(base >= 2 && base <= 36);
|
2022-01-24 01:59:16 +00:00
|
|
|
|
2022-05-30 09:49:58 +00:00
|
|
|
// Write prefix
|
2022-06-01 12:45:36 +00:00
|
|
|
if (prefix) {
|
|
|
|
for (size_t prefix_len = 1; *prefix; ++prefix_len) {
|
|
|
|
if (prefix_len > KERNAUX_NTOA_MAX_PREFIX_LEN) {
|
|
|
|
// Protect caller from invalid state
|
|
|
|
*buffer = '\0';
|
2022-06-13 16:28:00 +00:00
|
|
|
KERNAUX_PANIC("prefix is too long");
|
2022-06-01 12:45:36 +00:00
|
|
|
}
|
|
|
|
*(buffer++) = *(prefix++);
|
|
|
|
}
|
|
|
|
}
|
2022-05-30 09:49:58 +00:00
|
|
|
|
|
|
|
// Write number
|
2022-01-18 07:39:28 +00:00
|
|
|
char *pos = buffer;
|
|
|
|
if (value == 0) *(pos++) = '0';
|
|
|
|
while (value > 0) {
|
2022-01-24 01:59:16 +00:00
|
|
|
const char mod = value % base;
|
|
|
|
*(pos++) = mod < 10 ? mod + '0' : mod - 10 + alpha;
|
2022-01-24 02:32:11 +00:00
|
|
|
value /= base;
|
2022-01-18 07:39:28 +00:00
|
|
|
}
|
2022-01-24 01:59:16 +00:00
|
|
|
char *const result = pos;
|
2022-01-18 07:39:28 +00:00
|
|
|
*(pos--) = '\0';
|
|
|
|
|
2022-05-30 09:49:58 +00:00
|
|
|
// Reverse number
|
2022-01-18 07:39:28 +00:00
|
|
|
while (buffer < pos) {
|
|
|
|
const char tmp = *buffer;
|
|
|
|
*(buffer++) = *pos;
|
|
|
|
*(pos--) = tmp;
|
|
|
|
}
|
2022-01-24 01:59:16 +00:00
|
|
|
|
|
|
|
return result;
|
2022-01-18 07:39:28 +00:00
|
|
|
}
|
2022-01-18 08:12:54 +00:00
|
|
|
|
2022-05-30 09:49:58 +00:00
|
|
|
char *kernaux_itoa(int64_t value, char *buffer, int base, const char *const prefix)
|
2022-01-18 08:12:54 +00:00
|
|
|
{
|
|
|
|
if (value >= 0) {
|
2022-05-30 09:49:58 +00:00
|
|
|
return kernaux_utoa(value, buffer, base, prefix);
|
2022-01-18 08:12:54 +00:00
|
|
|
} else {
|
|
|
|
*(buffer++) = '-';
|
2022-05-30 09:49:58 +00:00
|
|
|
return kernaux_utoa(-value, buffer, base, prefix);
|
2022-01-18 08:12:54 +00:00
|
|
|
}
|
|
|
|
}
|
2022-01-23 21:40:13 +00:00
|
|
|
|
2022-05-30 20:11:16 +00:00
|
|
|
char *kernaux_utoa2(uint64_t value, char *buffer)
|
|
|
|
{
|
|
|
|
return kernaux_utoa(value, buffer, 'b', KERNAUX_NTOA_DEFAULT_PREFIX_2);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *kernaux_itoa2(int64_t value, char *buffer)
|
|
|
|
{
|
|
|
|
return kernaux_itoa(value, buffer, 'b', KERNAUX_NTOA_DEFAULT_PREFIX_2);
|
|
|
|
}
|
|
|
|
|
2022-05-30 19:33:53 +00:00
|
|
|
char *kernaux_utoa8(uint64_t value, char *buffer)
|
|
|
|
{
|
|
|
|
return kernaux_utoa(value, buffer, 'o', KERNAUX_NTOA_DEFAULT_PREFIX_8);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *kernaux_itoa8(int64_t value, char *buffer)
|
|
|
|
{
|
|
|
|
return kernaux_itoa(value, buffer, 'o', KERNAUX_NTOA_DEFAULT_PREFIX_8);
|
|
|
|
}
|
|
|
|
|
2022-05-30 13:37:53 +00:00
|
|
|
char *kernaux_utoa10(uint64_t value, char *buffer)
|
2022-01-23 21:40:13 +00:00
|
|
|
{
|
2022-05-30 13:37:53 +00:00
|
|
|
return kernaux_utoa(value, buffer, 'd', NULL);
|
2022-01-24 01:59:16 +00:00
|
|
|
}
|
2022-01-23 21:40:13 +00:00
|
|
|
|
2022-05-30 13:37:53 +00:00
|
|
|
char *kernaux_itoa10(int64_t value, char *buffer)
|
2022-01-24 01:59:16 +00:00
|
|
|
{
|
2022-05-30 13:37:53 +00:00
|
|
|
return kernaux_itoa(value, buffer, 'd', NULL);
|
2022-01-24 01:59:16 +00:00
|
|
|
}
|
2022-01-23 21:40:13 +00:00
|
|
|
|
2022-05-30 13:37:53 +00:00
|
|
|
char *kernaux_utoa16(uint64_t value, char *buffer)
|
2022-01-24 01:59:16 +00:00
|
|
|
{
|
2022-05-30 14:04:35 +00:00
|
|
|
return kernaux_utoa(value, buffer, 'x', KERNAUX_NTOA_DEFAULT_PREFIX_16);
|
2022-01-23 21:40:13 +00:00
|
|
|
}
|
|
|
|
|
2022-05-30 13:37:53 +00:00
|
|
|
char *kernaux_itoa16(int64_t value, char *buffer)
|
2022-01-23 21:40:13 +00:00
|
|
|
{
|
2022-05-30 14:04:35 +00:00
|
|
|
return kernaux_itoa(value, buffer, 'x', KERNAUX_NTOA_DEFAULT_PREFIX_16);
|
2022-01-23 21:40:13 +00:00
|
|
|
}
|