Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 5 commits
  • 10 files changed
  • 0 commit comments
  • 1 contributor
1  software/bios/main.c
View
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include <stdlib.h>
#include <console.h>
#include <string.h>
#include <uart.h>
72 software/include/base/ctype.h
View
@@ -1,51 +1,55 @@
#ifndef __CTYPE_H
#define __CTYPE_H
-static inline int isdigit(char c)
-{
- return (c >= '0') && (c <= '9');
-}
-
-static inline int isxdigit(char c)
-{
- return isdigit(c) || ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F'));
-}
-
-static inline int isupper(char c)
-{
- return (c >= 'A') && (c <= 'Z');
-}
-
-static inline int islower(char c)
-{
- return (c >= 'a') && (c <= 'z');
-}
-
-static inline unsigned char tolower(unsigned char c)
+/*
+ * NOTE! This ctype does not handle EOF like the standard C
+ * library is required to.
+ */
+
+#define _U 0x01 /* upper */
+#define _L 0x02 /* lower */
+#define _D 0x04 /* digit */
+#define _C 0x08 /* cntrl */
+#define _P 0x10 /* punct */
+#define _S 0x20 /* white space (space/lf/tab) */
+#define _X 0x40 /* hex digit */
+#define _SP 0x80 /* hard space (0x20) */
+
+extern const unsigned char _ctype[];
+
+#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
+
+#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
+#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0)
+#define iscntrl(c) ((__ismask(c)&(_C)) != 0)
+#define isdigit(c) ((__ismask(c)&(_D)) != 0)
+#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0)
+#define islower(c) ((__ismask(c)&(_L)) != 0)
+#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
+#define ispunct(c) ((__ismask(c)&(_P)) != 0)
+/* Note: isspace() must return false for %NUL-terminator */
+#define isspace(c) ((__ismask(c)&(_S)) != 0)
+#define isupper(c) ((__ismask(c)&(_U)) != 0)
+#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
+
+#define isascii(c) (((unsigned char)(c))<=0x7f)
+#define toascii(c) (((unsigned char)(c))&0x7f)
+
+static inline unsigned char __tolower(unsigned char c)
{
if (isupper(c))
c -= 'A'-'a';
return c;
}
-static inline unsigned char toupper(unsigned char c)
+static inline unsigned char __toupper(unsigned char c)
{
if (islower(c))
c -= 'a'-'A';
return c;
}
-static inline char isspace(unsigned char c)
-{
- if(c == ' '
- || c == '\f'
- || c == '\n'
- || c == '\r'
- || c == '\t'
- || c == '\v')
- return 1;
-
- return 0;
-}
+#define tolower(c) __tolower(c)
+#define toupper(c) __toupper(c)
#endif /* __CTYPE_H */
253 software/include/base/errno.h
View
@@ -0,0 +1,253 @@
+#ifndef __ERRNO_H
+#define __ERRNO_H
+
+extern int errno;
+
+#define EPERM 1
+#define EPERM_STR "Operation not permitted"
+#define ENOENT 2
+#define ENOENT_STR "No such file or directory"
+#define ESRCH 3
+#define ESRCH_STR "No such process"
+#define EINTR 4
+#define EINTR_STR "Interrupted system call"
+#define EIO 5
+#define EIO_STR "I/O error"
+#define ENXIO 6
+#define ENXIO_STR "No such device or address"
+#define E2BIG 7
+#define E2BIG_STR "Arg list too long"
+#define ENOEXEC 8
+#define ENOEXEC_STR "Exec format error"
+#define EBADF 9
+#define EBADF_STR "Bad file number"
+#define ECHILD 10
+#define ECHILD_STR "No child processes"
+#define EAGAIN 11
+#define EWOULDBLOCK EAGAIN
+#define EAGAIN_STR "Try again"
+#define ENOMEM 12
+#define ENOMEM_STR "Out of memory"
+#define EACCES 13
+#define EACCES_STR "Permission denied"
+#define EFAULT 14
+#define EFAULT_STR "Bad address"
+#define ENOTBLK 15
+#define ENOTBLK_STR "Block device required"
+#define EBUSY 16
+#define EBUSY_STR "Device or resource busy"
+#define EEXIST 17
+#define EEXIST_STR "File exists"
+#define EXDEV 18
+#define EXDEV_STR "Cross-device link"
+#define ENODEV 19
+#define ENODEV_STR "No such device"
+#define ENOTDIR 20
+#define ENOTDIR_STR "Not a directory"
+#define EISDIR 21
+#define EISDIR_STR "Is a directory"
+#define EINVAL 22
+#define EINVAL_STR "Invalid argument"
+#define ENFILE 23
+#define ENFILE_STR "File table overflow"
+#define EMFILE 24
+#define EMFILE_STR "Too many open files"
+#define ENOTTY 25
+#define ENOTTY_STR "Not a typewriter"
+#define ETXTBSY 26
+#define ETXTBSY_STR "Text file busy"
+#define EFBIG 27
+#define EFBIG_STR "File too large"
+#define ENOSPC 28
+#define ENOSPC_STR "No space left on device"
+#define ESPIPE 29
+#define ESPIPE_STR "Illegal seek"
+#define EROFS 30
+#define EROFS_STR "Read-only file system"
+#define EMLINK 31
+#define EMLINK_STR "Too many links"
+#define EPIPE 32
+#define EPIPE_STR "Broken pipe"
+#define EDOM 33
+#define EDOM_STR "Math argument out of domain of func"
+#define ERANGE 34
+#define ERANGE_STR "Math result not representable"
+#define EDEADLK 35
+#define EDEADLOCK EDEADLK
+#define EDEADLK_STR "Resource deadlock would occur"
+#define ENAMETOOLONG 36
+#define ENAMETOOLONG_STR "File name too long"
+#define ENOLCK 37
+#define ENOLCK_STR "No record locks available"
+#define ENOSYS 38
+#define ENOSYS_STR "Function not implemented"
+#define ENOTEMPTY 39
+#define ENOTEMPTY_STR "Directory not empty"
+#define ELOOP 40
+#define ELOOP_STR "Too many symbolic links encountered"
+#define ENOMSG 42
+#define ENOMSG_STR "No message of desired type"
+#define EIDRM 43
+#define EIDRM_STR "Identifier removed"
+#define ECHRNG 44
+#define ECHRNG_STR "Channel number out of range"
+#define EL2NSYNC 45
+#define EL2NSYNC_STR "Level 2 not synchronized"
+#define EL3HLT 46
+#define EL3HLT_STR "Level 3 halted"
+#define EL3RST 47
+#define EL3RST_STR "Level 3 reset"
+#define ELNRNG 48
+#define ELNRNG_STR "Link number out of range"
+#define EUNATCH 49
+#define EUNATCH_STR "Protocol driver not attached"
+#define ENOCSI 50
+#define ENOCSI_STR "No CSI structure available"
+#define EL2HLT 51
+#define EL2HLT_STR "Level 2 halted"
+#define EBADE 52
+#define EBADE_STR "Invalid exchange"
+#define EBADR 53
+#define EBADR_STR "Invalid request descriptor"
+#define EXFULL 54
+#define EXFULL_STR "Exchange full"
+#define ENOANO 55
+#define ENOANO_STR "No anode"
+#define EBADRQC 56
+#define EBADRQC_STR "Invalid request code"
+#define EBADSLT 57
+#define EBADSLT_STR "Invalid slot"
+#define EBFONT 59
+#define EBFONT_STR "Bad font file format"
+#define ENOSTR 60
+#define ENOSTR_STR "Device not a stream"
+#define ENODATA 61
+#define ENODATA_STR "No data available"
+#define ETIME 62
+#define ETIME_STR "Timer expired"
+#define ENOSR 63
+#define ENOSR_STR "Out of streams resources"
+#define ENONET 64
+#define ENONET_STR "Machine is not on the network"
+#define ENOPKG 65
+#define ENOPKG_STR "Package not installed"
+#define EREMOTE 66
+#define EREMOTE_STR "Object is remote"
+#define ENOLINK 67
+#define ENOLINK_STR "Link has been severed"
+#define EADV 68
+#define EADV_STR "Advertise error"
+#define ESRMNT 69
+#define ESRMNT_STR "Srmount error"
+#define ECOMM 70
+#define ECOMM_STR "Communication error on send"
+#define EPROTO 71
+#define EPROTO_STR "Protocol error"
+#define EMULTIHOP 72
+#define EMULTIHOP_STR "Multihop attempted"
+#define EDOTDOT 73
+#define EDOTDOT_STR "RFS specific error"
+#define EBADMSG 74
+#define EBADMSG_STR "Not a data message"
+#define EOVERFLOW 75
+#define EOVERFLOW_STR "Value too large for defined data type"
+#define ENOTUNIQ 76
+#define ENOTUNIQ_STR "Name not unique on network"
+#define EBADFD 77
+#define EBADFD_STR "File descriptor in bad state"
+#define EREMCHG 78
+#define EREMCHG_STR "Remote address changed"
+#define ELIBACC 79
+#define ELIBACC_STR "Can not access a needed shared library"
+#define ELIBBAD 80
+#define ELIBBAD_STR "Accessing a corrupted shared library"
+#define ELIBSCN 81
+#define ELIBSCN_STR ".lib section in a.out corrupted"
+#define ELIBMAX 82
+#define ELIBMAX_STR "Attempting to link in too many shared libraries"
+#define ELIBEXEC 83
+#define ELIBEXEC_STR "Cannot exec a shared library directly"
+#define EILSEQ 84
+#define EILSEQ_STR "Illegal byte sequence"
+#define ERESTART 85
+#define ERESTART_STR "Interrupted system call should be restarted"
+#define ESTRPIPE 86
+#define ESTRPIPE_STR "Streams pipe error"
+#define EUSERS 87
+#define EUSERS_STR "Too many users"
+#define ENOTSOCK 88
+#define ENOTSOCK_STR "Socket operation on non-socket"
+#define EDESTADDRREQ 89
+#define EDESTADDRREQ_STR "Destination address required"
+#define EMSGSIZE 90
+#define EMSGSIZE_STR "Message too long"
+#define EPROTOTYPE 91
+#define EPROTOTYPE_STR "Protocol wrong type for socket"
+#define ENOPROTOOPT 92
+#define ENOPROTOOPT_STR "Protocol not available"
+#define EPROTONOSUPPORT 93
+#define EPROTONOSUPPORT_STR "Protocol not supported"
+#define ESOCKTNOSUPPORT 94
+#define ESOCKTNOSUPPORT_STR "Socket type not supported"
+#define EOPNOTSUPP 95
+#define EOPNOTSUPP_STR "Operation not supported on transport endpoint"
+#define EPFNOSUPPORT 96
+#define EPFNOSUPPORT_STR "Protocol family not supported"
+#define EAFNOSUPPORT 97
+#define EAFNOSUPPORT_STR "Address family not supported by protocol"
+#define EADDRINUSE 98
+#define EADDRINUSE_STR "Address already in use"
+#define EADDRNOTAVAIL 99
+#define EADDRNOTAVAIL_STR "Cannot assign requested address"
+#define ENETDOWN 100
+#define ENETDOWN_STR "Network is down"
+#define ENETUNREACH 101
+#define ENETUNREACH_STR "Network is unreachable"
+#define ENETRESET 102
+#define ENETRESET_STR "Network dropped connection because of reset"
+#define ECONNABORTED 103
+#define ECONNABORTED_STR "Software caused connection abort"
+#define ECONNRESET 104
+#define ECONNRESET_STR "Connection reset by peer"
+#define ENOBUFS 105
+#define ENOBUFS_STR "No buffer space available"
+#define EISCONN 106
+#define EISCONN_STR "Transport endpoint is already connected"
+#define ENOTCONN 107
+#define ENOTCONN_STR "Transport endpoint is not connected"
+#define ESHUTDOWN 108
+#define ESHUTDOWN_STR "Cannot send after transport endpoint shutdown"
+#define ETOOMANYREFS 109
+#define ETOOMANYREFS_STR "Too many references: cannot splice"
+#define ETIMEDOUT 110
+#define ETIMEDOUT_STR "Connection timed out"
+#define ECONNREFUSED 111
+#define ECONNREFUSED_STR "Connection refused"
+#define EHOSTDOWN 112
+#define EHOSTDOWN_STR "Host is down"
+#define EHOSTUNREACH 113
+#define EHOSTUNREACH_STR "No route to host"
+#define EALREADY 114
+#define EALREADY_STR "Operation already in progress"
+#define EINPROGRESS 115
+#define EINPROGRESS_STR "Operation now in progress"
+#define ESTALE 116
+#define ESTALE_STR "Stale NFS file handle"
+#define EUCLEAN 117
+#define EUCLEAN_STR "Structure needs cleaning"
+#define ENOTNAM 118
+#define ENOTNAM_STR "Not a XENIX named type file"
+#define ENAVAIL 119
+#define ENAVAIL_STR "No XENIX semaphores available"
+#define EISNAM 120
+#define EISNAM_STR "Is a named type file"
+#define EREMOTEIO 121
+#define EREMOTEIO_STR "Remote I/O error"
+#define EDQUOT 122
+#define EDQUOT_STR "Quota exceeded"
+#define ENOMEDIUM 123
+#define ENOMEDIUM_STR "No medium found"
+#define EMEDIUMTYPE 124
+#define EMEDIUMTYPE_STR "Wrong medium type"
+
+#endif /* __ERRNO_H */
26 software/include/base/stdio.h
View
@@ -1,7 +1,7 @@
#ifndef __STDIO_H
#define __STDIO_H
-#include <stdlib.h>
+#include <stddef.h>
int putchar(int c);
int puts(const char *s);
@@ -12,4 +12,28 @@ int sprintf(char *buf, const char *fmt, ...);
int printf(const char *fmt, ...);
+/*
+ * Note: this library does not provide FILE operations.
+ * User code must implement them.
+ */
+
+#ifndef BUFSIZ
+#define BUFSIZ 1024
+#endif
+
+typedef int FILE;
+
+extern FILE *stdin;
+extern FILE *stdout;
+extern FILE *stderr;
+
+int fprintf(FILE *stream, const char *format, ...);
+int fflush(FILE *stream);
+
+FILE *fopen(const char *path, const char *mode);
+char *fgets(char *s, int size, FILE *stream);
+size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
+int fclose(FILE *fp);
+
#endif /* __STDIO_H */
8 software/include/base/stdlib.h
View
@@ -44,7 +44,7 @@ static inline long atol(const char *nptr) {
}
char *number(char *buf, char *end, unsigned long num, int base, int size, int precision, int type);
long strtol(const char *nptr, char **endptr, int base);
-float atof(const char *s);
+double strtod(const char *str, char **endptr);
#define RAND_MAX 2147483647
@@ -52,4 +52,10 @@ unsigned int rand(void);
void srand(unsigned int seed);
void abort(void);
+/*
+ * The following functions are not provided by this library.
+ */
+
+char *getenv(const char *name);
+
#endif /* __STDLIB_H */
5 software/include/base/string.h
View
@@ -19,9 +19,10 @@
#ifndef __STRING_H
#define __STRING_H
-#include <stdlib.h>
+#include <stddef.h>
char *strchr(const char *s, int c);
+char *strpbrk(const char *,const char *);
char *strrchr(const char *s, int c);
char *strnchr(const char *s, size_t count, int c);
char *strcpy(char *dest, const char *src);
@@ -30,10 +31,12 @@ int strcmp(const char *cs, const char *ct);
int strncmp(const char *cs, const char *ct, size_t count);
size_t strlen(const char *s);
size_t strnlen(const char *s, size_t count);
+size_t strspn(const char *s, const char *accept);
int memcmp(const void *cs, const void *ct, size_t count);
void *memset(void *s, int c, size_t count);
void *memcpy(void *to, const void *from, size_t n);
void *memmove(void *dest, const void *src, size_t count);
char *strstr(const char *s1, const char *s2);
+void *memchr(const void *s, int c, size_t n);
#endif /* __STRING_H */
2  software/libbase/Makefile
View
@@ -1,7 +1,7 @@
M2DIR=../..
include $(M2DIR)/software/common.mak
-OBJECTS=divsi3.o setjmp.o libc.o crc16.o crc32.o console.o timer.o system.o board.o uart.o softfloat.o softfloat-glue.o vsnprintf.o atof.o
+OBJECTS=divsi3.o setjmp.o libc.o crc16.o crc32.o console.o timer.o system.o board.o uart.o softfloat.o softfloat-glue.o vsnprintf.o strtod.o
all: libbase.a
84 software/libbase/atof.c
View
@@ -1,84 +0,0 @@
-/* atof.c: converts an ASCII string to float
-
- Copyright (C) 2003 Jesus Calvino-Fraga, jesusc@ieee.org
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#include <stdlib.h>
-#include <ctype.h>
-
-float atof(const char * s)
-{
- float value, fraction;
- char iexp;
- char sign;
-
- //Skip leading blanks
- while (isspace(*s)) s++;
-
- //Get the sign
- if (*s == '-')
- {
- sign=1;
- s++;
- }
- else
- {
- sign=0;
- if (*s == '+') s++;
- }
-
- //Get the integer part
- for (value=0.0f; isdigit(*s); s++)
- {
- value=10.0f*value+(*s-'0');
- }
-
- //Get the fraction
- if (*s == '.')
- {
- s++;
- for (fraction=0.1f; isdigit(*s); s++)
- {
- value+=(*s-'0')*fraction;
- fraction*=0.1f;
- }
- }
-
- //Finally, the exponent (not very efficient, but enough for now)
- if (toupper(*s)=='E')
- {
- s++;
- iexp=(char)atoi(s);
- {
- while(iexp!=0)
- {
- if(iexp<0)
- {
- value*=0.1f;
- iexp++;
- }
- else
- {
- value*=10.0f;
- iexp--;
- }
- }
- }
- }
-
- if(sign) value*=-1.0f;
- return (value);
-}
90 software/libbase/libc.c
View
@@ -23,6 +23,8 @@
#include <string.h>
#include <limits.h>
+int errno;
+
/**
* strchr - Find the first occurrence of a character in a string
* @s: The string to be searched
@@ -37,6 +39,24 @@ char *strchr(const char *s, int c)
}
/**
+ * strpbrk - Find the first occurrence of a set of characters
+ * @cs: The string to be searched
+ * @ct: The characters to search for
+ */
+char *strpbrk(const char *cs, const char *ct)
+{
+ const char *sc1, *sc2;
+
+ for (sc1 = cs; *sc1 != '\0'; ++sc1) {
+ for (sc2 = ct; *sc2 != '\0'; ++sc2) {
+ if (*sc1 == *sc2)
+ return (char *)sc1;
+ }
+ }
+ return NULL;
+}
+
+/**
* strrchr - Find the last occurrence of a character in a string
* @s: The string to be searched
* @c: The character to search for
@@ -170,6 +190,29 @@ size_t strnlen(const char *s, size_t count)
}
/**
+ * strspn - Calculate the length of the initial substring of @s which only contain letters in @accept
+ * @s: The string to be searched
+ * @accept: The string to search for
+ */
+size_t strspn(const char *s, const char *accept)
+{
+ const char *p;
+ const char *a;
+ size_t count = 0;
+
+ for (p = s; *p != '\0'; ++p) {
+ for (a = accept; *a != '\0'; ++a) {
+ if (*p == *a)
+ break;
+ }
+ if (*a == '\0')
+ return count;
+ ++count;
+ }
+ return count;
+}
+
+/**
* memcmp - Compare two areas of memory
* @cs: One area of memory
* @ct: Another area of memory
@@ -302,6 +345,26 @@ char *strstr(const char *s1, const char *s2)
}
/**
+ * memchr - Find a character in an area of memory.
+ * @s: The memory area
+ * @c: The byte to search for
+ * @n: The size of the area.
+ *
+ * returns the address of the first occurrence of @c, or %NULL
+ * if @c is not found
+ */
+void *memchr(const void *s, int c, size_t n)
+{
+ const unsigned char *p = s;
+ while (n-- != 0) {
+ if ((unsigned char)c == *p++) {
+ return (void *)(p - 1);
+ }
+ }
+ return NULL;
+}
+
+/**
* strtoul - convert a string to an unsigned long
* @nptr: The start of the string
* @endptr: A pointer to the end of the parsed string will be placed here
@@ -559,6 +622,33 @@ int sprintf(char * buf, const char *fmt, ...)
return i;
}
+/* From linux/lib/ctype.c, Copyright (C) 1991, 1992 Linus Torvalds */
+const unsigned char _ctype[] = {
+_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
+_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
+_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
+_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
+_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
+_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
+_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
+_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
+_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
+_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
+_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
+_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
+_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
+_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
+_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
+_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
+_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
+_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
+
/**
* rand - Returns a pseudo random number
*/
234 software/libbase/strtod.c
View
@@ -0,0 +1,234 @@
+/****************************************************************************
+ * lib/string/lib_strtod.c
+ * Convert string to double
+ *
+ * Copyright (C) 2002 Michael Ringgaard. All rights reserved.
+ * Copyright (C) 2006-2007 H. Peter Anvin.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+
+/****************************************************************************
+ * Pre-processor definitions
+ ****************************************************************************/
+
+/* These are predefined with GCC, but could be issues for other compilers. If
+ * not defined, an arbitrary big number is put in for now. These should be
+ * added to nuttx/compiler for your compiler.
+ */
+
+#if !defined(__DBL_MIN_EXP__) || !defined(__DBL_MAX_EXP__)
+# ifdef CONFIG_CPP_HAVE_WARNING
+# warning "Size of exponent is unknown"
+# endif
+# undef __DBL_MIN_EXP__
+# define __DBL_MIN_EXP__ (-1021)
+# undef __DBL_MAX_EXP__
+# define __DBL_MAX_EXP__ (1024)
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static inline int is_real(double x)
+{
+ const double infinite = 1.0/0.0;
+ return (x < infinite) && (x >= -infinite);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/***************************************************(************************
+ * Name: strtod
+ *
+ * Description:
+ * Convert a string to a double value
+ *
+ ****************************************************************************/
+
+double strtod(const char *str, char **endptr)
+{
+ double number;
+ int exponent;
+ int negative;
+ char *p = (char *) str;
+ double p10;
+ int n;
+ int num_digits;
+ int num_decimals;
+ const double infinite = 1.0/0.0;
+
+ /* Skip leading whitespace */
+
+ while (isspace(*p))
+ {
+ p++;
+ }
+
+ /* Handle optional sign */
+
+ negative = 0;
+ switch (*p)
+ {
+ case '-':
+ negative = 1; /* Fall through to increment position */
+ case '+':
+ p++;
+ }
+
+ number = 0.;
+ exponent = 0;
+ num_digits = 0;
+ num_decimals = 0;
+
+ /* Process string of digits */
+
+ while (isdigit(*p))
+ {
+ number = number * 10. + (*p - '0');
+ p++;
+ num_digits++;
+ }
+
+ /* Process decimal part */
+
+ if (*p == '.')
+ {
+ p++;
+
+ while (isdigit(*p))
+ {
+ number = number * 10. + (*p - '0');
+ p++;
+ num_digits++;
+ num_decimals++;
+ }
+
+ exponent -= num_decimals;
+ }
+
+ if (num_digits == 0)
+ {
+ errno = ERANGE;
+ return 0.0;
+ }
+
+ /* Correct for sign */
+
+ if (negative)
+ {
+ number = -number;
+ }
+
+ /* Process an exponent string */
+
+ if (*p == 'e' || *p == 'E')
+ {
+ /* Handle optional sign */
+
+ negative = 0;
+ switch(*++p)
+ {
+ case '-':
+ negative = 1; /* Fall through to increment pos */
+ case '+':
+ p++;
+ }
+
+ /* Process string of digits */
+
+ n = 0;
+ while (isdigit(*p))
+ {
+ n = n * 10 + (*p - '0');
+ p++;
+ }
+
+ if (negative)
+ {
+ exponent -= n;
+ }
+ else
+ {
+ exponent += n;
+ }
+ }
+
+ if (exponent < __DBL_MIN_EXP__ ||
+ exponent > __DBL_MAX_EXP__)
+ {
+ errno = ERANGE;
+ return infinite;
+ }
+
+ /* Scale the result */
+
+ p10 = 10.;
+ n = exponent;
+ if (n < 0) n = -n;
+ while (n)
+ {
+ if (n & 1)
+ {
+ if (exponent < 0)
+ {
+ number /= p10;
+ }
+ else
+ {
+ number *= p10;
+ }
+ }
+ n >>= 1;
+ p10 *= p10;
+ }
+
+ if (!is_real(number))
+ {
+ errno = ERANGE;
+ }
+
+ if (endptr)
+ {
+ *endptr = p;
+ }
+
+ return number;
+}
+

No commit comments for this range

Something went wrong with that request. Please try again.