hydroforth/src/hydroforth/number.c

110 lines
1.7 KiB
C

#include <stdbool.h>
#include <stddef.h>
#include "hydroforth/number.h"
bool hydroforth__number__is_digit(char c)
{
return '0' <= c && c <= '9';
}
bool hydroforth__number__convert_hex_digit(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:
return false;
}
}
return true;
}
bool hydroforth__number__parse_number_hex(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(start[i], &m))
{
return false;
}
n *= 16;
n += m;
}
return true;
}
bool hydroforth__number__parse_number(const char *const start, unsigned char len, int *const val)
{
if (start[0] == '0')
{
if (len > 1)
{
switch (start[1])
{
case 'X':
case 'x':
return hydroforth__number__parse_number_hex(start + 2, len - 2, val);
default:
return hydroforth__number__parse_number(start + 1, len - 1, val);
}
}
else
{
*val = 0;
return true;
}
}
else
{
int n = start[0] - '0';
for (unsigned char i = 1; i < len; i++)
{
n *= 10;
n += start[i] - '0';
}
*val = n;
return true;
}
}