136 lines
2.3 KiB
C
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;
|
|
}
|
|
}
|