110 lines
1.7 KiB
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;
|
|
}
|
|
}
|