mirror of https://github.com/flysand7/ciabatta.git
separate out conv stuff
This commit is contained in:
parent
4d4449a5d9
commit
bc443e31c3
|
@ -37,10 +37,9 @@
|
|||
|
||||
#include "intrin.h"
|
||||
|
||||
#include "util.c"
|
||||
|
||||
// Dependencies
|
||||
#include "decfloat/decfloat.c"
|
||||
#include "util.c"
|
||||
#include "conv/decfloat/decfloat.c"
|
||||
|
||||
// Platform-independent stuff
|
||||
#include "fmt/gen_fmt.c"
|
||||
|
@ -49,7 +48,10 @@
|
|||
#include "math/gen_math.c"
|
||||
#include "math/ieee754.c"
|
||||
#include "math/round.c"
|
||||
#include "conv/conversion.c"
|
||||
#include "conv/digits.c"
|
||||
#include "conv/strpfx.c"
|
||||
#include "conv/int.c"
|
||||
#include "conv/float.c"
|
||||
#include "stdlib/algorithm.c"
|
||||
#include "stdlib/multibyte.c"
|
||||
#include "stdlib/random.c"
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
static inline bool isbase(int c, int base) {
|
||||
int val = 0;
|
||||
if(isdigit(c)) {
|
||||
val = c-'0';
|
||||
}
|
||||
else if(islower(c)) {
|
||||
val = c-'a'+10;
|
||||
}
|
||||
else if(isupper(c)) {
|
||||
val = c-'A'+10;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return val < base;
|
||||
}
|
||||
|
||||
static inline intl todigit(int c) {
|
||||
int val = 0;
|
||||
if(isdigit(c)) {
|
||||
val = c-'0';
|
||||
}
|
||||
else if(islower(c)) {
|
||||
val = c-'a'+10;
|
||||
}
|
||||
else if(isupper(c)) {
|
||||
val = c-'A'+10;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
|
||||
|
||||
static f64 strtod_generic(const char *restrict nptr, char **restrict endptr) {
|
||||
const char *restrict str = nptr;
|
||||
bool conv_performed = false;
|
||||
f64 value = 0.0;
|
||||
f64 coef = 1.0;
|
||||
// Skip space on the beginning
|
||||
while(isspace(*str)) {
|
||||
++str;
|
||||
}
|
||||
// Check for inf and nan
|
||||
if(strpfx_i(str, "INF")) {
|
||||
str += sizeof "INF"-1;
|
||||
value = HUGE_VAL;
|
||||
conv_performed = true;
|
||||
goto finish;
|
||||
}
|
||||
if(strpfx_i(str, "INFINITY")) {
|
||||
str += sizeof "INFINITY"-1;
|
||||
value = HUGE_VAL;
|
||||
conv_performed = true;
|
||||
goto finish;
|
||||
}
|
||||
if(strpfx_i(str, "NAN")) {
|
||||
str += sizeof "NAN"-1;
|
||||
value = NAN;
|
||||
conv_performed = true;
|
||||
if(*str == '(') {
|
||||
while(*str != ')') {
|
||||
++str;
|
||||
}
|
||||
++str;
|
||||
}
|
||||
goto finish;
|
||||
}
|
||||
// Parse C float
|
||||
if(*str == '+') {
|
||||
++str;
|
||||
}
|
||||
else if(*str == '-') {
|
||||
coef = -1.;
|
||||
++str;
|
||||
}
|
||||
int base = 10;
|
||||
if(strpfx_i(str, "0X")) {
|
||||
str += sizeof "0X"-1;
|
||||
base = 16;
|
||||
}
|
||||
// Parse the whole part
|
||||
while(isbase(*str, base)) {
|
||||
long digit = todigit(*str);
|
||||
value = 10.0*value + (f64)digit;
|
||||
++str;
|
||||
}
|
||||
if(*str != '.') {
|
||||
value = 0.0;
|
||||
goto finish;
|
||||
}
|
||||
++str;
|
||||
// Parse the fractional part
|
||||
long exp = 1;
|
||||
while(isbase(*str, base)) {
|
||||
long digit = todigit(*str);
|
||||
f64 fract = (f64)digit;
|
||||
long cexp = exp;
|
||||
while(cexp-- != 0) {
|
||||
fract /= (f64)base;
|
||||
}
|
||||
value += fract;
|
||||
++exp;
|
||||
++str;
|
||||
}
|
||||
// Parse the exponent
|
||||
if((base == 10 && strpfx_i(str, "E"))
|
||||
|| (base == 16 && strpfx_i(str, "P")))
|
||||
{
|
||||
++str;
|
||||
long exp = 0;
|
||||
long exp_coef = 1;
|
||||
if(*str == '+') {
|
||||
++str;
|
||||
}
|
||||
else if(*str == '-') {
|
||||
exp_coef = -1;
|
||||
++str;
|
||||
}
|
||||
while(isdigit(*str)) {
|
||||
exp = 10*exp + (long)(*str-'0');
|
||||
++str;
|
||||
}
|
||||
if(exp_coef == 1) {
|
||||
while(exp--!=0) value = value * base;
|
||||
}
|
||||
else if(exp_coef == -1) {
|
||||
while(exp--!=0) value = value / base;
|
||||
}
|
||||
}
|
||||
if(!isfinite(value)) {
|
||||
errno = ERANGE;
|
||||
value = coef*HUGE_VAL;
|
||||
}
|
||||
conv_performed = true;
|
||||
finish:
|
||||
if(endptr != NULL) {
|
||||
if(conv_performed) {
|
||||
*endptr = (char *)str;
|
||||
}
|
||||
else {
|
||||
*endptr = (char *)nptr;
|
||||
}
|
||||
}
|
||||
return coef*value;
|
||||
}
|
||||
|
||||
f64 strtod(const char *restrict nptr, char **restrict endptr) {
|
||||
return strtod_generic(nptr, endptr);
|
||||
}
|
||||
|
||||
f32 strtof(const char *restrict nptr, char **restrict endptr) {
|
||||
return (f32)strtod_generic(nptr, endptr);
|
||||
}
|
||||
|
||||
fl64 strtold(const char *restrict nptr, char **restrict endptr) {
|
||||
return (fl64)strtod_generic(nptr, endptr);
|
||||
}
|
||||
|
||||
f64 atof(const char *nptr) {
|
||||
return strtod(nptr, (char **)NULL);
|
||||
}
|
|
@ -1,46 +1,4 @@
|
|||
|
||||
static bool isbase(int c, int base) {
|
||||
int val = 0;
|
||||
if(isdigit(c)) {
|
||||
val = c-'0';
|
||||
}
|
||||
else if(islower(c)) {
|
||||
val = c-'a'+10;
|
||||
}
|
||||
else if(isupper(c)) {
|
||||
val = c-'A'+10;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return val < base;
|
||||
}
|
||||
|
||||
static bool strprefix_i(char const *restrict str, char const *restrict prefix) {
|
||||
while(*prefix != 0) {
|
||||
if(*str == 0) break;
|
||||
if(toupper(*str) != toupper(*prefix)) return false;
|
||||
++prefix;
|
||||
++str;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called only when isbase(c, base) for some base in range
|
||||
static long todigit(int c) {
|
||||
int val = 0;
|
||||
if(isdigit(c)) {
|
||||
val = c-'0';
|
||||
}
|
||||
else if(islower(c)) {
|
||||
val = c-'a'+10;
|
||||
}
|
||||
else if(isupper(c)) {
|
||||
val = c-'A'+10;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static intull strtoi_generic(const char *restrict nptr,
|
||||
char **restrict endptr,
|
||||
int inbase,
|
||||
|
@ -77,7 +35,7 @@ static intull strtoi_generic(const char *restrict nptr,
|
|||
}
|
||||
// See if we need to parse base in C-like format
|
||||
// then set the base accordingly
|
||||
if(strprefix_i(str, "0X")) {
|
||||
if(strpfx_i(str, "0X")) {
|
||||
++str;
|
||||
if(base == 16 || base == 0) {
|
||||
++str;
|
||||
|
@ -140,119 +98,6 @@ static intull strtoi_generic(const char *restrict nptr,
|
|||
return value;
|
||||
}
|
||||
|
||||
static double strtod_generic(const char *restrict nptr, char **restrict endptr) {
|
||||
const char *restrict str = nptr;
|
||||
bool conv_performed = false;
|
||||
double value = 0.0;
|
||||
double coef = 1.0;
|
||||
// Skip space on the beginning
|
||||
while(isspace(*str)) {
|
||||
++str;
|
||||
}
|
||||
// Check for inf and nan
|
||||
if(strprefix_i(str, "INF")) {
|
||||
str += sizeof "INF"-1;
|
||||
value = HUGE_VAL;
|
||||
conv_performed = true;
|
||||
goto finish;
|
||||
}
|
||||
if(strprefix_i(str, "INFINITY")) {
|
||||
str += sizeof "INFINITY"-1;
|
||||
value = HUGE_VAL;
|
||||
conv_performed = true;
|
||||
goto finish;
|
||||
}
|
||||
if(strprefix_i(str, "NAN")) {
|
||||
str += sizeof "NAN"-1;
|
||||
value = NAN;
|
||||
conv_performed = true;
|
||||
if(*str == '(') {
|
||||
while(*str != ')') {
|
||||
++str;
|
||||
}
|
||||
++str;
|
||||
}
|
||||
goto finish;
|
||||
}
|
||||
// Parse C float
|
||||
if(*str == '+') {
|
||||
++str;
|
||||
}
|
||||
else if(*str == '-') {
|
||||
coef = -1.;
|
||||
++str;
|
||||
}
|
||||
int base = 10;
|
||||
if(strprefix_i(str, "0X")) {
|
||||
str += sizeof "0X"-1;
|
||||
base = 16;
|
||||
}
|
||||
// Parse the whole part
|
||||
while(isbase(*str, base)) {
|
||||
long digit = todigit(*str);
|
||||
value = 10.0*value + (double)digit;
|
||||
++str;
|
||||
}
|
||||
if(*str != '.') {
|
||||
value = 0.0;
|
||||
goto finish;
|
||||
}
|
||||
++str;
|
||||
// Parse the fractional part
|
||||
long exp = 1;
|
||||
while(isbase(*str, base)) {
|
||||
long digit = todigit(*str);
|
||||
double fract = (double)digit;
|
||||
long cexp = exp;
|
||||
while(cexp-- != 0) {
|
||||
fract /= (double)base;
|
||||
}
|
||||
value += fract;
|
||||
++exp;
|
||||
++str;
|
||||
}
|
||||
// Parse the exponent
|
||||
if((base == 10 && strprefix_i(str, "E"))
|
||||
|| (base == 16 && strprefix_i(str, "P")))
|
||||
{
|
||||
++str;
|
||||
long exp = 0;
|
||||
long exp_coef = 1;
|
||||
if(*str == '+') {
|
||||
++str;
|
||||
}
|
||||
else if(*str == '-') {
|
||||
exp_coef = -1;
|
||||
++str;
|
||||
}
|
||||
while(isdigit(*str)) {
|
||||
exp = 10*exp + (long)(*str-'0');
|
||||
++str;
|
||||
}
|
||||
if(exp_coef == 1) {
|
||||
while(exp--!=0) value = value * base;
|
||||
}
|
||||
else if(exp_coef == -1) {
|
||||
while(exp--!=0) value = value / base;
|
||||
}
|
||||
}
|
||||
if(!isfinite(value)) {
|
||||
errno = ERANGE;
|
||||
value = coef*HUGE_VAL;
|
||||
}
|
||||
conv_performed = true;
|
||||
finish:
|
||||
if(endptr != NULL) {
|
||||
if(conv_performed) {
|
||||
*endptr = (char *)str;
|
||||
}
|
||||
else {
|
||||
*endptr = (char *)nptr;
|
||||
}
|
||||
}
|
||||
return coef*value;
|
||||
}
|
||||
|
||||
intl strtol(const char *restrict nptr, char **restrict endptr, int base) {
|
||||
intull int_max = (intull)LONG_MAX;
|
||||
intl coef;
|
||||
|
@ -292,10 +137,6 @@ intull strtoull(const char *restrict nptr, char **restrict endptr, int base) {
|
|||
return strtoi_generic(nptr, endptr, base, NULL, int_max);
|
||||
}
|
||||
|
||||
double atof(const char *nptr) {
|
||||
return strtod(nptr, (char **)NULL);
|
||||
}
|
||||
|
||||
int atoi(const char *nptr) {
|
||||
return (int)strtol(nptr, (char **)NULL, 10);
|
||||
}
|
||||
|
@ -308,18 +149,6 @@ long long int atoll(const char *nptr) {
|
|||
return strtoll(nptr, (char **)NULL, 10);
|
||||
}
|
||||
|
||||
double strtod(const char *restrict nptr, char **restrict endptr) {
|
||||
return strtod_generic(nptr, endptr);
|
||||
}
|
||||
|
||||
float strtof(const char *restrict nptr, char **restrict endptr) {
|
||||
return (float)strtod_generic(nptr, endptr);
|
||||
}
|
||||
|
||||
long double strtold(const char *restrict nptr, char **restrict endptr) {
|
||||
return (long double)strtod_generic(nptr, endptr);
|
||||
}
|
||||
|
||||
char *itoa(int value, char *str, int base) {
|
||||
int sign = 0;
|
||||
if(value < 0) {
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
static bool strpfx_i(char const *restrict str, char const *restrict prefix) {
|
||||
while(*prefix != 0) {
|
||||
if(*str == 0) break;
|
||||
if(toupper(*str) != toupper(*prefix)) return false;
|
||||
++prefix;
|
||||
++str;
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -32,9 +32,12 @@ typedef unsigned int intu;
|
|||
typedef unsigned long int intul;
|
||||
typedef unsigned long long int intull;
|
||||
|
||||
typedef float f32;
|
||||
typedef double f64;
|
||||
typedef long double fl64;
|
||||
|
||||
typedef wchar_t wchar;
|
||||
|
||||
#define COUNTOF(arr) (sizeof (arr) / sizeof ((arr)[0]))
|
||||
#define IN_RANGE(start, v, end) ((start) <= (v) && (v) <= (end))
|
||||
|
||||
#define CONCAT(a,b) a ## b
|
||||
|
|
Loading…
Reference in New Issue