hydroforth/src/hydroforth/number.c
2022-12-23 17:16:29 +01:00

136 lines
2.3 KiB
C

#include <stdbool.h>
#include <stddef.h>
#include "hydroforth/hydroforth.h"
bool hydroforth__number__is_digit(char c)
{
return '0' <= c && c <= '9';
}
unsigned char hydroforth__number__convert_hex_digit(HYDROFORTH__RESULT *const result, char c)
{
if (hydroforth__number__is_digit(c))
{
return c - '0';
}
else
{
switch (c)
{
case 'A':
case 'a':
return 0xa;
case 'B':
case 'b':
return 0xb;
case 'C':
case 'c':
return 0xc;
case 'D':
case 'd':
return 0xd;
case 'E':
case 'e':
return 0xe;
case 'F':
case 'f':
return 0xf;
default:
// hydroforth__result__set(result, ERR_INVALID_HEX_CHAR, __func__);
hydroforth__set_func_result(result, ERR_INVALID_HEX_CHAR);
break;
}
}
}
int hydroforth__number__parse_number_hex(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len)
{
int n = 0;
for (unsigned char i = 0; i < len; i++)
{
unsigned char m = hydroforth__number__convert_hex_digit(result, start[i]);
if (result->error)
{
hydroforth__add_func_backtrace(result);
return 0;
}
n *= 16;
n += m;
}
return n;
}
int hydroforth__number__parse_number(HYDROFORTH__RESULT *const result, const char *const start, unsigned char len)
{
if (start[0] == '0')
{
if (len > 1)
{
switch (start[1])
{
case 'X':
case 'x':
{
int n = hydroforth__number__parse_number_hex(result, start + 2, len - 2);
if (result->error)
{
hydroforth__add_func_backtrace(result);
}
return n;
}
default:
{
int n = hydroforth__number__parse_number(result, start + 1, len - 1);
if (result->error)
{
hydroforth__add_func_backtrace(result);
}
return n;
}
}
}
else
{
return 0;
}
}
else
{
int n = start[0] - '0';
for (unsigned char i = 1; i < len; i++)
{
n *= 10;
n += start[i] - '0';
}
return n;
}
}
unsigned char hydroforth__number__count_digits(int n)
{
if (n == 0)
{
return 1;
}
else
{
unsigned char res = 0;
while (n != 0)
{
n /= 10;
res++;
}
return res;
}
}