Skip to content

Commit

Permalink
Improve strings.h (#26)
Browse files Browse the repository at this point in the history
* Add strtof and strtoi

* Support octal and hexadecimal strings in strtoi

* Don't use register keyword
After benchmarks, it does look like using register keyword is actually slower on z80
  • Loading branch information
aviallon committed Jun 14, 2020
1 parent f5597ea commit 3222d70
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 0 deletions.
11 changes: 11 additions & 0 deletions include/strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,15 @@ int strcasecmp(const char *, const char *);
int strncasecmp(const char *, const char *, size_t);
//int strncasecmp_l(const char *, const char *, size_t, locale_t);

/**
* Mostly ANSI compliant strtof function - converts a string into a float, ignoring blanks at the begining
**/
float strtof (unsigned char* str, char** endptr);

/**
* Mostly ANSI compliant strtoi function - converts a string into an int, ignoring blanks at the begining
* Does not yet support non decimal bases
**/
int strtoi (unsigned char* str, char** endptr);

#endif
124 changes: 124 additions & 0 deletions src/strings.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,127 @@ int strncasecmp(const char *s1, const char *s2, size_t n) {

return result;
}

float strtof (unsigned char* str, char** endptr) {
unsigned char *ptr = str;
bool is_neg = false;
bool overflow = false;
float result = 0;
int c;
float frac_base = 0.1;
int exponent = 0;

while ( isspace(*ptr) )
ptr += 1;

if(*ptr == '+') {
ptr += 1;
} else if (*ptr == '-'){
ptr += 1;
is_neg = true;
}

// Integer part
while (1) {
c = *ptr;
if (c == '\0' || c < '0' || c > '9') {
break;
}

c = c - '0';
result = result * 10 + c;
ptr += 1;
}

// Fractionnal part
if ( *ptr == '.' ){
ptr += 1;
while(1) {
c = *ptr;
if (c == '\0' || c < '0' || c > '9') {
break;
}
c = c - '0';

result += frac_base * c;
frac_base /= 10;
ptr += 1;
}
}

// Exponent part
if ( *ptr == 'e' ){
ptr += 1;
while(1) {
c = *ptr;
if (c == '\0' || c < '0' || c > '9') {
break;
}
c = c - '0';

exponent = exponent * 10 + c;
ptr += 1;
}

result = result * powf(10, exponent);
}

if(is_neg)
result = -result;

if (endptr != 0)
*endptr = ptr;

return result;
}

int strtoi (unsigned char* str, char** endptr) {
unsigned char *ptr = str;
bool is_neg = false;
bool overflow = false;
int result = 0;
unsigned base = 10;

while ( isspace(*ptr) ) {
ptr += 1;
}

if (*ptr == '+') {
ptr += 1;
} else if(*ptr == '-') {
ptr += 1;
is_neg = true;
}

if (*ptr == '0' ) {
base = 8;
ptr += 1;
if (*ptr == 'x' ) {
base = 16;
ptr += 1;
}
}

while (1) {
int c = *ptr;
if (c == '\0' || c < '0' || c > '9') {
break;
}
c = c - '0';
if (result > (INT_MAX/base - c)) {
overflow = true;
ptr += 1;
continue;
}
result = result * base + c;
ptr += 1;
}

if (endptr != 0)
*endptr = ptr;

if (is_neg)
result = -result;

return result;
}

0 comments on commit 3222d70

Please sign in to comment.