This is an automated email from the ASF dual-hosted git repository.
kasjer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
The following commit(s) were added to refs/heads/master by this push:
new 79d699bc4 baselibc: Add strtof implementation
79d699bc4 is described below
commit 79d699bc42b0b40aeb74a9c9fefc6aa6405a0296
Author: Jerzy Kasenberg <[email protected]>
AuthorDate: Mon Jun 22 08:56:23 2026 +0200
baselibc: Add strtof implementation
While strtof has prototype in stdlib.h there was
no implementation of this function, meaning compiler
would search for this function in standard libraries.
This would not be a problem for other functions
mostly math functions do not have implementations
in baselibc.
However this function in libraries provided by arm
gcc is really using _strtod_l which works on double
precission numbers, moreover this _strtod_l forces
inclusion of other code that baselibc already
covers like malloc/free it can also lead to inclusion
of other function and eventually conflicts during
link time.
This provide local strtof implemenation that does not
depends on anything.
For now hex string literals are not covered.
Signed-off-by: Jerzy Kasenberg <[email protected]>
---
libc/baselibc/src/mynewt.c | 160 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 160 insertions(+)
diff --git a/libc/baselibc/src/mynewt.c b/libc/baselibc/src/mynewt.c
index a8f12ee7d..3c79a80dd 100644
--- a/libc/baselibc/src/mynewt.c
+++ b/libc/baselibc/src/mynewt.c
@@ -18,6 +18,8 @@
*/
#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
#include <console/console.h>
#include <os/os_time.h>
#include <os/os_mutex.h>
@@ -54,6 +56,164 @@ fflush(FILE *stream)
return 0;
}
+static const char *
+eat_spaces(const char *p)
+{
+ while (isspace(*p)) {
+ ++p;
+ }
+
+ return p;
+}
+
+static const char *
+eat_sign(const char *p, int *sign)
+{
+ *sign = 1;
+
+ if (*p == '+' || *p == '-') {
+ *sign = ',' - *p;
+ ++p;
+ }
+
+ return p;
+}
+
+static const char *
+eat_base(const char *p, int *base)
+{
+ if (*p == '0' && (p[1] == 'x' || p[1] == 'X')) {
+ *base = 16;
+ p += 2;
+ } else {
+ *base = 10;
+ }
+ return p;
+}
+
+static const char *
+eat_leading_zeros(const char *p)
+{
+ while (*p == '0') {
+ ++p;
+ }
+
+ return p;
+}
+
+static const char *
+eat_digits(const char *p, unsigned int *n, bool frac, int *exp)
+{
+ unsigned int val = *n;
+
+ while (isdigit(*p)) {
+ if (val < 429496729) {
+ val = val * 10 + *p - '0';
+ if (frac) {
+ --*exp;
+ }
+ } else if (!frac && exp) {
+ ++*exp;
+ }
+ ++p;
+ }
+ *n = val;
+
+ return p;
+}
+
+static float
+fexp10(int mant, int n)
+{
+ float result = (float)mant;
+ float mul = 10.0f;
+ bool plus = n >= 0;
+
+ n = abs(n);
+
+ for (; n != 0; n >>= 1) {
+ if (n & 1) {
+ if (plus) {
+ result *= mul;
+ } else {
+ result /= mul;
+ }
+ }
+ mul = mul * mul;
+ }
+ return result;
+}
+
+static bool
+eat_dot(const char **s)
+{
+ if (**s == '.') {
+ ++*s;
+ return true;
+ }
+ return false;
+}
+
+static bool
+eat_e(const char **s)
+{
+ if (**s == 'E' || **s == 'e') {
+ ++*s;
+ return true;
+ }
+ return false;
+}
+
+float
+strtof(const char *str, char **strend)
+{
+ const char *p = str;
+ int sign;
+ int base;
+ unsigned int mant = 0;
+ int exp = 0;
+ int exp_sign = 1;
+ float f = 0;
+
+ p = eat_spaces(p);
+ p = eat_sign(p, &sign);
+ p = eat_base(p, &base);
+ p = eat_leading_zeros(p);
+ if (base == 10) {
+ p = eat_digits(p, &mant, false, &exp);
+ if (eat_dot(&p)) {
+ if (mant == 0) {
+ const char *s = p;
+ p = eat_leading_zeros(p);
+ exp = s - p;
+ }
+ p = eat_digits(p, &mant, true, &exp);
+ }
+ if (eat_e(&p)) {
+ unsigned int exp1 = 0;
+
+ p = eat_sign(p, &exp_sign);
+ p = eat_leading_zeros(p);
+ p = eat_digits(p, &exp1, false, NULL);
+ exp += exp_sign * exp1;
+ }
+ if (exp > 45) {
+ f = exp_sign == 1 ? INFINITY : 0.0f;
+ } else if (exp == 0) {
+ f = (float)mant;
+ } else {
+ f = fexp10(mant, exp);
+ }
+ f *= sign;
+ } else if (base == 16) {
+ /* Not implemented */
+ }
+ if (strend) {
+ *strend = (char *)p;
+ }
+ return f;
+}
+
#if MYNEWT_VAL(BASELIBC_THREAD_SAFE_HEAP_ALLOCATION)
static struct os_mutex heap_mutex;