hydroforth/src/hydroforth/number.c
2022-12-23 15:02:29 +01:00

144 lines
2.5 KiB
C

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