summaryrefslogtreecommitdiff
path: root/firmware/libc
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-05-06 21:04:40 +0000
committerThomas Martitz <kugel@rockbox.org>2010-05-06 21:04:40 +0000
commit50a6ca39ad4ed01922aa4f755f0ca579788226cf (patch)
treec7881b015b220558167310345b162324c96be15a /firmware/libc
parentadb506df14aded06ed6e9ebf8540e6fd383ffd6a (diff)
downloadrockbox-50a6ca39ad4ed01922aa4f755f0ca579788226cf.tar.gz
rockbox-50a6ca39ad4ed01922aa4f755f0ca579788226cf.zip
Move c/h files implementing/defining standard library stuff into a new libc directory, also standard'ify some parts of the code base (almost entirely #include fixes).
This is to a) to cleanup firmware/common and firmware/include a bit, but also b) for Rockbox as an application which should use the host system's c library and headers, separating makes it easy to exclude our files from the build. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25850 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/libc')
-rw-r--r--firmware/libc/atoi.c57
-rw-r--r--firmware/libc/ctype.c22
-rw-r--r--firmware/libc/errno.c1
-rw-r--r--firmware/libc/include/ctype.h75
-rw-r--r--firmware/libc/include/errno.h145
-rw-r--r--firmware/libc/include/inttypes.h29
-rw-r--r--firmware/libc/include/stdint.h107
-rw-r--r--firmware/libc/include/stdio.h60
-rw-r--r--firmware/libc/include/stdlib.h58
-rw-r--r--firmware/libc/include/string.h94
-rw-r--r--firmware/libc/include/time.h49
-rw-r--r--firmware/libc/memchr.c116
-rw-r--r--firmware/libc/memcmp.c113
-rw-r--r--firmware/libc/memcpy.c117
-rw-r--r--firmware/libc/memmove.c147
-rw-r--r--firmware/libc/memset.c110
-rw-r--r--firmware/libc/mktime.c61
-rw-r--r--firmware/libc/qsort.c222
-rw-r--r--firmware/libc/random.c119
-rw-r--r--firmware/libc/sprintf.c93
-rw-r--r--firmware/libc/sscanf.c282
-rw-r--r--firmware/libc/strcat.c14
-rw-r--r--firmware/libc/strchr.c108
-rw-r--r--firmware/libc/strcmp.c106
-rw-r--r--firmware/libc/strcpy.c99
-rw-r--r--firmware/libc/strlen.c93
-rw-r--r--firmware/libc/strncmp.c122
-rw-r--r--firmware/libc/strrchr.c59
-rw-r--r--firmware/libc/strstr.c38
-rw-r--r--firmware/libc/strtok.c63
30 files changed, 2779 insertions, 0 deletions
diff --git a/firmware/libc/atoi.c b/firmware/libc/atoi.c
new file mode 100644
index 0000000000..3393839b27
--- /dev/null
+++ b/firmware/libc/atoi.c
@@ -0,0 +1,57 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Gary Czvitkovicz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdlib.h>
23#include "ctype.h"
24
25int atoi (const char *str)
26{
27 int value = 0;
28 int sign = 1;
29
30 while (isspace(*str))
31 {
32 str++;
33 }
34
35 if ('-' == *str)
36 {
37 sign = -1;
38 str++;
39 }
40 else if ('+' == *str)
41 {
42 str++;
43 }
44
45 while ('0' == *str)
46 {
47 str++;
48 }
49
50 while (isdigit(*str))
51 {
52 value = (value * 10) + (*str - '0');
53 str++;
54 }
55
56 return value * sign;
57}
diff --git a/firmware/libc/ctype.c b/firmware/libc/ctype.c
new file mode 100644
index 0000000000..6e9b4eb601
--- /dev/null
+++ b/firmware/libc/ctype.c
@@ -0,0 +1,22 @@
1#include <ctype.h>
2
3const unsigned char _ctype_[257]={
4 0,
5 _C, _C, _C, _C, _C, _C, _C, _C,
6 _C, _C|_S, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C,
7 _C, _C, _C, _C, _C, _C, _C, _C,
8 _C, _C, _C, _C, _C, _C, _C, _C,
9 _S|_B, _P, _P, _P, _P, _P, _P, _P,
10 _P, _P, _P, _P, _P, _P, _P, _P,
11 _N, _N, _N, _N, _N, _N, _N, _N,
12 _N, _N, _P, _P, _P, _P, _P, _P,
13 _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U,
14 _U, _U, _U, _U, _U, _U, _U, _U,
15 _U, _U, _U, _U, _U, _U, _U, _U,
16 _U, _U, _U, _P, _P, _P, _P, _P,
17 _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L,
18 _L, _L, _L, _L, _L, _L, _L, _L,
19 _L, _L, _L, _L, _L, _L, _L, _L,
20 _L, _L, _L, _P, _P, _P, _P, _C
21};
22
diff --git a/firmware/libc/errno.c b/firmware/libc/errno.c
new file mode 100644
index 0000000000..6e7bb62b51
--- /dev/null
+++ b/firmware/libc/errno.c
@@ -0,0 +1 @@
int errno;
diff --git a/firmware/libc/include/ctype.h b/firmware/libc/include/ctype.h
new file mode 100644
index 0000000000..648e06dc5c
--- /dev/null
+++ b/firmware/libc/include/ctype.h
@@ -0,0 +1,75 @@
1#ifndef _CTYPE_H_
2#ifdef __cplusplus
3extern "C" {
4#endif
5#define _CTYPE_H_
6
7#include "_ansi.h"
8
9int _EXFUN(isalnum, (int __c));
10int _EXFUN(isalpha, (int __c));
11int _EXFUN(iscntrl, (int __c));
12int _EXFUN(isdigit, (int __c));
13int _EXFUN(isgraph, (int __c));
14int _EXFUN(islower, (int __c));
15int _EXFUN(isprint, (int __c));
16int _EXFUN(ispunct, (int __c));
17int _EXFUN(isspace, (int __c));
18int _EXFUN(isupper, (int __c));
19int _EXFUN(isxdigit,(int __c));
20int _EXFUN(tolower, (int __c));
21int _EXFUN(toupper, (int __c));
22
23#ifndef __STRICT_ANSI__
24int _EXFUN(isascii, (int __c));
25int _EXFUN(toascii, (int __c));
26int _EXFUN(_tolower, (int __c));
27int _EXFUN(_toupper, (int __c));
28#endif
29
30#define _U 01
31#define _L 02
32#define _N 04
33#define _S 010
34#define _P 020
35#define _C 040
36#define _X 0100
37#define _B 0200
38
39#ifdef PLUGIN
40#define _ctype_ (rb->_rbctype_)
41#else
42extern const unsigned char _ctype_[257];
43#endif
44
45#ifndef __cplusplus
46#define isalpha(c) ((_ctype_+1)[(unsigned char)(c)]&(_U|_L))
47#define isupper(c) ((_ctype_+1)[(unsigned char)(c)]&_U)
48#define islower(c) ((_ctype_+1)[(unsigned char)(c)]&_L)
49#define isdigit(c) ((_ctype_+1)[(unsigned char)(c)]&_N)
50#define isxdigit(c) ((_ctype_+1)[(unsigned char)(c)]&(_X|_N))
51#define isspace(c) ((_ctype_+1)[(unsigned char)(c)]&_S)
52#define ispunct(c) ((_ctype_+1)[(unsigned char)(c)]&_P)
53#define isalnum(c) ((_ctype_+1)[(unsigned char)(c)]&(_U|_L|_N))
54#define isprint(c) ((_ctype_+1)[(unsigned char)(c)]&(_P|_U|_L|_N|_B))
55#define isgraph(c) ((_ctype_+1)[(unsigned char)(c)]&(_P|_U|_L|_N))
56#define iscntrl(c) ((_ctype_+1)[(unsigned char)(c)]&_C)
57/* Non-gcc versions will get the library versions, and will be
58 slightly slower */
59#ifdef __GNUC__
60# define toupper(c) \
61 __extension__ ({ int __x = (unsigned char) (c); islower(__x) ? (__x - 'a' + 'A') : __x;})
62# define tolower(c) \
63 __extension__ ({ int __x = (unsigned char) (c); isupper(__x) ? (__x - 'A' + 'a') : __x;})
64#endif
65#endif /* !__cplusplus */
66
67#ifndef __STRICT_ANSI__
68#define isascii(c) ((unsigned char)(c)<=0177)
69#define toascii(c) ((c)&0177)
70#endif
71
72#ifdef __cplusplus
73}
74#endif
75#endif /* _CTYPE_H_ */
diff --git a/firmware/libc/include/errno.h b/firmware/libc/include/errno.h
new file mode 100644
index 0000000000..6a24a1938f
--- /dev/null
+++ b/firmware/libc/include/errno.h
@@ -0,0 +1,145 @@
1/* errno is not a global variable, because that would make using it
2 non-reentrant. Instead, its address is returned by the function
3 __errno. */
4
5#if (defined(SIMULATOR)||defined(__PCTOOL__)) && !defined(__MINGW32__) && !defined(__CYGWIN__)
6
7#include "/usr/include/errno.h" /* use the host system implementation */
8
9#else /* use our own implementation */
10
11#ifndef _SYS_ERRNO_H_
12
13#ifdef PLUGIN
14#define errno (*rb->__errno)
15#else
16extern int errno;
17#endif
18
19#define EPERM 1 /* Not super-user */
20#define ENOENT 2 /* No such file or directory */
21#define ESRCH 3 /* No such process */
22#define EINTR 4 /* Interrupted system call */
23#define EIO 5 /* I/O error */
24#define ENXIO 6 /* No such device or address */
25#define E2BIG 7 /* Arg list too long */
26#define ENOEXEC 8 /* Exec format error */
27#define EBADF 9 /* Bad file number */
28#define ECHILD 10 /* No children */
29#define EAGAIN 11 /* No more processes */
30#define ENOMEM 12 /* Not enough core */
31#define EACCES 13 /* Permission denied */
32#define EFAULT 14 /* Bad address */
33#define ENOTBLK 15 /* Block device required */
34#define EBUSY 16 /* Mount device busy */
35#define EEXIST 17 /* File exists */
36#define EXDEV 18 /* Cross-device link */
37#define ENODEV 19 /* No such device */
38#define ENOTDIR 20 /* Not a directory */
39#define EISDIR 21 /* Is a directory */
40#define EINVAL 22 /* Invalid argument */
41#define ENFILE 23 /* Too many open files in system */
42#define EMFILE 24 /* Too many open files */
43#define ENOTTY 25 /* Not a typewriter */
44#define ETXTBSY 26 /* Text file busy */
45#define EFBIG 27 /* File too large */
46#define ENOSPC 28 /* No space left on device */
47#define ESPIPE 29 /* Illegal seek */
48#define EROFS 30 /* Read only file system */
49#define EMLINK 31 /* Too many links */
50#define EPIPE 32 /* Broken pipe */
51#define EDOM 33 /* Math arg out of domain of func */
52#define ERANGE 34 /* Math result not representable */
53#define ENOMSG 35 /* No message of desired type */
54#define EIDRM 36 /* Identifier removed */
55#define ECHRNG 37 /* Channel number out of range */
56#define EL2NSYNC 38 /* Level 2 not synchronized */
57#define EL3HLT 39 /* Level 3 halted */
58#define EL3RST 40 /* Level 3 reset */
59#define ELNRNG 41 /* Link number out of range */
60#define EUNATCH 42 /* Protocol driver not attached */
61#define ENOCSI 43 /* No CSI structure available */
62#define EL2HLT 44 /* Level 2 halted */
63#define EDEADLK 45 /* Deadlock condition */
64#define ENOLCK 46 /* No record locks available */
65#define EBADE 50 /* Invalid exchange */
66#define EBADR 51 /* Invalid request descriptor */
67#define EXFULL 52 /* Exchange full */
68#define ENOANO 53 /* No anode */
69#define EBADRQC 54 /* Invalid request code */
70#define EBADSLT 55 /* Invalid slot */
71#define EDEADLOCK 56 /* File locking deadlock error */
72#define EBFONT 57 /* Bad font file fmt */
73#define ENOSTR 60 /* Device not a stream */
74#define ENODATA 61 /* No data (for no delay io) */
75#define ETIME 62 /* Timer expired */
76#define ENOSR 63 /* Out of streams resources */
77#define ENONET 64 /* Machine is not on the network */
78#define ENOPKG 65 /* Package not installed */
79#define EREMOTE 66 /* The object is remote */
80#define ENOLINK 67 /* The link has been severed */
81#define EADV 68 /* Advertise error */
82#define ESRMNT 69 /* Srmount error */
83#define ECOMM 70 /* Communication error on send */
84#define EPROTO 71 /* Protocol error */
85#define EMULTIHOP 74 /* Multihop attempted */
86#define ELBIN 75 /* Inode is remote (not really error) */
87#define EDOTDOT 76 /* Cross mount point (not really error) */
88#define EBADMSG 77 /* Trying to read unreadable message */
89#define ENOTUNIQ 80 /* Given log. name not unique */
90#define EBADFD 81 /* f.d. invalid for this operation */
91#define EREMCHG 82 /* Remote address changed */
92#define ELIBACC 83 /* Can't access a needed shared lib */
93#define ELIBBAD 84 /* Accessing a corrupted shared lib */
94#define ELIBSCN 85 /* .lib section in a.out corrupted */
95#define ELIBMAX 86 /* Attempting to link in too many libs */
96#define ELIBEXEC 87 /* Attempting to exec a shared library */
97#define ENOSYS 88 /* Function not implemented */
98#define ENMFILE 89 /* No more files */
99#define ENOTEMPTY 90 /* Directory not empty */
100#define ENAMETOOLONG 91 /* File or path name too long */
101#define ELOOP 92 /* Too many symbolic links */
102#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
103#define EPFNOSUPPORT 96 /* Protocol family not supported */
104#define ECONNRESET 104 /* Connection reset by peer */
105#define ENOBUFS 105 /* No buffer space available */
106#define EAFNOSUPPORT 106 /* Address family not supported by protocol family */
107#define EPROTOTYPE 107 /* Protocol wrong type for socket */
108#define ENOTSOCK 108 /* Socket operation on non-socket */
109#define ENOPROTOOPT 109 /* Protocol not available */
110#define ESHUTDOWN 110 /* Can't send after socket shutdown */
111#define ECONNREFUSED 111 /* Connection refused */
112#define EADDRINUSE 112 /* Address already in use */
113#define ECONNABORTED 113 /* Connection aborted */
114#define ENETUNREACH 114 /* Network is unreachable */
115#define ENETDOWN 115 /* Network interface is not configured */
116#define ETIMEDOUT 116 /* Connection timed out */
117#define EHOSTDOWN 117 /* Host is down */
118#define EHOSTUNREACH 118 /* Host is unreachable */
119#define EINPROGRESS 119 /* Connection already in progress */
120#define EALREADY 120 /* Socket already connected */
121#define EDESTADDRREQ 121 /* Destination address required */
122#define EMSGSIZE 122 /* Message too long */
123#define EPROTONOSUPPORT 123 /* Unknown protocol */
124#define ESOCKTNOSUPPORT 124 /* Socket type not supported */
125#define EADDRNOTAVAIL 125 /* Address not available */
126#define ENETRESET 126
127#define EISCONN 127 /* Socket is already connected */
128#define ENOTCONN 128 /* Socket is not connected */
129#define ETOOMANYREFS 129
130#define EPROCLIM 130
131#define EUSERS 131
132#define EDQUOT 132
133#define ESTALE 133
134#define ENOTSUP 134 /* Not supported */
135#define ENOMEDIUM 135 /* No medium (in tape drive) */
136#define ENOSHARE 136 /* No such host or network path */
137#define ECASECLASH 137 /* Filename exists with different case */
138
139/* From cygwin32. */
140#define EWOULDBLOCK EAGAIN /* Operation would block */
141
142#define __ELASTERROR 2000 /* Users can add values starting here */
143
144#endif /* _SYS_ERRNO_H */
145#endif /* !SIMULATOR */
diff --git a/firmware/libc/include/inttypes.h b/firmware/libc/include/inttypes.h
new file mode 100644
index 0000000000..c03609c6d8
--- /dev/null
+++ b/firmware/libc/include/inttypes.h
@@ -0,0 +1,29 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __INTTYPES_H__
23#define __INTTYPES_H__
24
25#include <stdint.h>
26
27/* could possibly have (f)printf format specifies here */
28
29#endif /* __INTTYPES_H__ */
diff --git a/firmware/libc/include/stdint.h b/firmware/libc/include/stdint.h
new file mode 100644
index 0000000000..93f234c0e8
--- /dev/null
+++ b/firmware/libc/include/stdint.h
@@ -0,0 +1,107 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __STDINT_H__
23#define __STDINT_H__
24
25#include <limits.h>
26
27/* 8 bit */
28#define INT8_MIN SCHAR_MIN
29#define INT8_MAX SCHAR_MAX
30#define UINT8_MAX UCHAR_MAX
31#define int8_t signed char
32#define uint8_t unsigned char
33
34/* 16 bit */
35#if USHRT_MAX == 0xffff
36
37#define INT16_MIN SHRT_MIN
38#define INT16_MAX SHRT_MAX
39#define UINT16_MAX USHRT_MAX
40#define int16_t short
41#define uint16_t unsigned short
42
43#endif
44
45/* 32 bit */
46#if ULONG_MAX == 0xfffffffful
47
48#define INT32_MIN LONG_MIN
49#define INT32_MAX LONG_MAX
50#define UINT32_MAX ULONG_MAX
51#define int32_t long
52#define uint32_t unsigned long
53
54#define INTPTR_MIN LONG_MIN
55#define INTPTR_MAX LONG_MAX
56#define UINTPTR_MAX ULONG_MAX
57#define intptr_t long
58#define uintptr_t unsigned long
59
60#elif UINT_MAX == 0xffffffffu
61
62#define INT32_MIN INT_MIN
63#define INT32_MAX INT_MAX
64#define UINT32_MAX UINT_MAX
65#define int32_t int
66#define uint32_t unsigned int
67
68#endif
69
70/* 64 bit */
71#ifndef LLONG_MIN
72#define LLONG_MIN ((long long)9223372036854775808ull)
73#endif
74
75#ifndef LLONG_MAX
76#define LLONG_MAX 9223372036854775807ll
77#endif
78
79#ifndef ULLONG_MAX
80#define ULLONG_MAX 18446744073709551615ull
81#endif
82
83#if ULONG_MAX == 0xffffffffffffffffull
84
85#define INT64_MIN LONG_MIN
86#define INT64_MAX LONG_MAX
87#define UINT64_MAX ULONG_MAX
88#define int64_t long
89#define uint64_t unsigned long
90
91#define INTPTR_MIN LONG_MIN
92#define INTPTR_MAX LONG_MAX
93#define UINTPTR_MAX ULONG_MAX
94#define intptr_t long
95#define uintptr_t unsigned long
96
97#else
98
99#define INT64_MIN LLONG_MIN
100#define INT64_MAX LLONG_MAX
101#define UINT64_MAX ULLONG_MAX
102#define int64_t long long
103#define uint64_t unsigned long long
104
105#endif
106
107#endif /* __STDINT_H__ */
diff --git a/firmware/libc/include/stdio.h b/firmware/libc/include/stdio.h
new file mode 100644
index 0000000000..d9a6dce55f
--- /dev/null
+++ b/firmware/libc/include/stdio.h
@@ -0,0 +1,60 @@
1#ifndef _STDIO_H_
2#define _STDIO_H_
3
4#include <_ansi.h>
5
6#define __need_size_t
7#include <stddef.h>
8
9#define __need___va_list
10#include <stdarg.h>
11
12#ifndef NULL
13#define NULL 0
14#endif
15
16#define EOF (-1)
17
18#ifndef SEEK_SET
19#define SEEK_SET 0 /* set file offset to offset */
20#endif
21#ifndef SEEK_CUR
22#define SEEK_CUR 1 /* set file offset to current plus offset */
23#endif
24#ifndef SEEK_END
25#define SEEK_END 2 /* set file offset to EOF plus offset */
26#endif
27
28#define TMP_MAX 26
29
30#ifdef __GNUC__
31#define __VALIST __gnuc_va_list
32#else
33#define __VALIST char*
34#endif
35
36int vsnprintf (char *buf, size_t size, const char *fmt, __VALIST ap);
37
38int sprintf (char *buf, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3);
39
40int snprintf (char *buf, size_t size, const char *fmt, ...)
41 ATTRIBUTE_PRINTF(3, 4);
42
43/* callback function is called for every output character (byte) with userp and
44 * should return 0 when ch is a char other than '\0' that should stop printing */
45int vuprintf(int (*push)(void *userp, unsigned char data),
46 void *userp, const char *fmt, __VALIST ap);
47
48int sscanf(const char *s, const char *fmt, ...)
49 ATTRIBUTE_SCANF(2, 3);
50
51#ifdef SIMULATOR
52typedef void FILE;
53int vfprintf(FILE *stream, const char *format, __VALIST ap);
54#ifdef WIN32
55#define FILENAME_MAX 260 /* ugly hard-coded value of a limit that is set
56 in file.h */
57#endif
58#endif
59
60#endif /* _STDIO_H_ */
diff --git a/firmware/libc/include/stdlib.h b/firmware/libc/include/stdlib.h
new file mode 100644
index 0000000000..5f6db6da8a
--- /dev/null
+++ b/firmware/libc/include/stdlib.h
@@ -0,0 +1,58 @@
1/*
2 * stdlib.h
3 *
4 * Definitions for common types, variables, and functions.
5 */
6
7#ifndef _STDLIB_H_
8#ifdef __cplusplus
9extern "C" {
10#endif
11#define _STDLIB_H_
12
13#include "_ansi.h"
14
15#define __need_size_t
16#define __need_wchar_t
17#include <stddef.h>
18
19#ifndef NULL
20#define NULL ((void*)0)
21#endif
22
23#define EXIT_FAILURE 1
24#define EXIT_SUCCESS 0
25
26_VOID _EXFUN(qsort,(_PTR __base, size_t __nmemb, size_t __size, int(*_compar)(const _PTR, const _PTR)));
27
28void *malloc(size_t);
29void *calloc (size_t nmemb, size_t size);
30void free(void *);
31void *realloc(void *, size_t);
32
33#define RAND_MAX INT_MAX
34
35void srand(unsigned int seed);
36int rand(void);
37
38#ifndef ABS
39#if defined(__GNUC__)
40#define ABS(a) ({typeof (a) ___a = (a); ___a < 0 ? -___a: ___a; })
41#else
42#define ABS(a) (((a) < 0) ? -(a) : (a))
43#endif /* __GNUC__ */
44#endif
45
46#define abs(x) ((int)ABS(x))
47#define labs(x) ((long)abs(x))
48
49#ifdef SIMULATOR
50void exit(int status);
51#endif
52
53int atoi (const char *str);
54
55#ifdef __cplusplus
56}
57#endif
58#endif /* _STDLIB_H_ */
diff --git a/firmware/libc/include/string.h b/firmware/libc/include/string.h
new file mode 100644
index 0000000000..8986bd6a0c
--- /dev/null
+++ b/firmware/libc/include/string.h
@@ -0,0 +1,94 @@
1/*
2 * string.h
3 *
4 * Definitions for memory and string functions.
5 */
6
7#ifndef _STRING_H_
8#define _STRING_H_
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14#include "_ansi.h"
15
16#include <stddef.h>
17
18#if !defined(__size_t_defined)&& !defined(_SIZE_T_) && !defined(size_t) && !defined(_SIZE_T_DECLARED)
19#define __size_t_defined
20#define _SIZE_T
21#define _SIZE_T_
22#define _SIZE_T_DECLARED
23#define size_t size_t
24typedef unsigned long size_t;
25#endif
26
27#ifndef NULL
28#define NULL ((void*)0)
29#endif
30
31_PTR _EXFUN(memchr,(const _PTR, int, size_t));
32int _EXFUN(memcmp,(const _PTR, const _PTR, size_t));
33_PTR _EXFUN(memcpy,(_PTR, const _PTR, size_t));
34_PTR _EXFUN(memmove,(_PTR, const _PTR, size_t));
35_PTR _EXFUN(memset,(_PTR, int, size_t));
36char *_EXFUN(strcat,(char *, const char *));
37char *_EXFUN(strchr,(const char *, int));
38int _EXFUN(strcmp,(const char *, const char *));
39int _EXFUN(strcoll,(const char *, const char *));
40char *_EXFUN(strcpy,(char *, const char *));
41size_t _EXFUN(strcspn,(const char *, const char *));
42char *_EXFUN(strerror,(int));
43size_t _EXFUN(strlen,(const char *));
44char *_EXFUN(strncat,(char *, const char *, size_t));
45int _EXFUN(strncmp,(const char *, const char *, size_t));
46char *_EXFUN(strpbrk,(const char *, const char *));
47char *_EXFUN(strrchr,(const char *, int));
48size_t _EXFUN(strspn,(const char *, const char *));
49char *_EXFUN(strstr,(const char *, const char *));
50char *_EXFUN(strcasestr,(const char *, const char *));
51
52size_t strlcpy(char *dst, const char *src, size_t siz);
53size_t strlcat(char *dst, const char *src, size_t siz);
54
55#ifndef _REENT_ONLY
56char *_EXFUN(strtok,(char *, const char *));
57#endif
58
59size_t _EXFUN(strxfrm,(char *, const char *, size_t));
60
61#ifndef __STRICT_ANSI__
62char *_EXFUN(strtok_r,(char *, const char *, char **));
63
64_PTR _EXFUN(memccpy,(_PTR, const _PTR, int, size_t));
65int _EXFUN(strcasecmp,(const char *, const char *));
66int _EXFUN(strncasecmp,(const char *, const char *, size_t));
67
68#ifdef __CYGWIN__
69#ifndef DEFS_H /* Kludge to work around problem compiling in gdb */
70const char *_EXFUN(strsignal, (int __signo));
71#endif
72int _EXFUN(strtosigno, (const char *__name));
73#endif
74
75/* These function names are used on Windows and perhaps other systems. */
76#ifndef strcmpi
77#define strcmpi strcasecmp
78#endif
79#ifndef stricmp
80#define stricmp strcasecmp
81#endif
82#ifndef strncmpi
83#define strncmpi strncasecmp
84#endif
85#ifndef strnicmp
86#define strnicmp strncasecmp
87#endif
88
89#endif /* ! __STRICT_ANSI__ */
90
91#ifdef __cplusplus
92}
93#endif
94#endif /* _STRING_H_ */
diff --git a/firmware/libc/include/time.h b/firmware/libc/include/time.h
new file mode 100644
index 0000000000..912fafe7ca
--- /dev/null
+++ b/firmware/libc/include/time.h
@@ -0,0 +1,49 @@
1/*
2 * time.h
3 *
4 * Struct declaration for dealing with time.
5 */
6
7#ifndef _TIME_H_
8#define _TIME_H_
9
10#ifdef WPSEDITOR
11#include "inttypes.h"
12#include <time.h>
13#endif
14
15struct tm
16{
17 int tm_sec;
18 int tm_min;
19 int tm_hour;
20 int tm_mday;
21 int tm_mon;
22 int tm_year;
23 int tm_wday;
24 int tm_yday;
25 int tm_isdst;
26};
27
28#if !defined(_TIME_T_DEFINED) && !defined(_TIME_T_DECLARED)
29typedef long time_t;
30
31/* this define below is used by the mingw headers to prevent duplicate
32 typedefs */
33#define _TIME_T_DEFINED
34#define _TIME_T_DECLARED
35time_t time(time_t *t);
36struct tm *localtime(const time_t *timep);
37time_t mktime(struct tm *t);
38
39#endif /* SIMULATOR */
40
41#ifdef __PCTOOL__
42/* this time.h does not define struct timespec,
43 so tell sys/stat.h not to use it */
44#undef __USE_MISC
45#endif
46
47#endif /* _TIME_H_ */
48
49
diff --git a/firmware/libc/memchr.c b/firmware/libc/memchr.c
new file mode 100644
index 0000000000..26bdb9eea3
--- /dev/null
+++ b/firmware/libc/memchr.c
@@ -0,0 +1,116 @@
1/*
2FUNCTION
3 <<memchr>>---search for character in memory
4
5INDEX
6 memchr
7
8ANSI_SYNOPSIS
9 #include <string.h>
10 void * memchr(const void *<[s1]>, int <[c]>, size_t <[n]>);
11
12TRAD_SYNOPSIS
13 #include <string.h>
14 void * memchr(<[s1]>, <[c]>, <[n]>);
15 void *<[string]>;
16 int *<[c]>;
17 size_t *<[n]>;
18
19DESCRIPTION
20 This function scans the first <[n]> bytes of the memory pointed
21 to by <[s1]> for the character <[c]> (converted to a char).
22
23RETURNS
24 Returns a pointer to the matching byte, or a null pointer if
25 <[c]> does not occur in <[s1]>.
26
27PORTABILITY
28<<memchr>> is ANSI C.
29
30<<memchr>> requires no supporting OS subroutines.
31
32QUICKREF
33 memchr ansi pure
34*/
35
36#include <string.h>
37#include <limits.h>
38
39/* Nonzero if X is not aligned on a "long" boundary. */
40#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
41
42/* How many bytes are loaded each iteration of the word copy loop. */
43#define LBLOCKSIZE (sizeof (long))
44
45#if LONG_MAX == 2147483647L
46#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
47#else
48#if LONG_MAX == 9223372036854775807L
49/* Nonzero if X (a long int) contains a NULL byte. */
50#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
51#else
52#error long int is not a 32bit or 64bit type.
53#endif
54#endif
55
56/* DETECTCHAR returns nonzero if (long)X contains the byte used
57 to fill (long)MASK. */
58#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK))
59
60void *
61_DEFUN (memchr, (s1, i, n),
62 _CONST void *s1 _AND
63 int i _AND size_t n)
64{
65 _CONST unsigned char *s = (_CONST unsigned char *)s1;
66#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
67 unsigned char c = (unsigned char)i;
68
69 while (n-- > 0)
70 {
71 if (*s == c)
72 {
73 return (void *)s;
74 }
75 s++;
76 }
77
78 return NULL;
79#else
80 unsigned char c = (unsigned char)i;
81 unsigned long mask,j;
82 unsigned long *aligned_addr;
83
84 if (!UNALIGNED (s))
85 {
86 mask = 0;
87 for (j = 0; j < LBLOCKSIZE; j++)
88 mask = (mask << 8) | c;
89
90 aligned_addr = (unsigned long*)s;
91 while ((!DETECTCHAR (*aligned_addr, mask)) && (n>LBLOCKSIZE))
92 {
93 aligned_addr++;
94 n -= LBLOCKSIZE;
95 }
96
97 /* The block of bytes currently pointed to by aligned_addr
98 may contain the target character or there may be less than
99 LBLOCKSIZE bytes left to search. We check the last few
100 bytes using the bytewise search. */
101
102 s = (unsigned char*)aligned_addr;
103 }
104
105 while (n-- > 0)
106 {
107 if (*s == c)
108 {
109 return (void *)s;
110 }
111 s++;
112 }
113
114 return NULL;
115#endif /* not PREFER_SIZE_OVER_SPEED */
116}
diff --git a/firmware/libc/memcmp.c b/firmware/libc/memcmp.c
new file mode 100644
index 0000000000..1535fcf5b5
--- /dev/null
+++ b/firmware/libc/memcmp.c
@@ -0,0 +1,113 @@
1/*
2FUNCTION
3 <<memcmp>>---compare two memory areas
4
5INDEX
6 memcmp
7
8ANSI_SYNOPSIS
9 #include <string.h>
10 int memcmp(const void *<[s1]>, const void *<[s2]>, size_t <[n]>);
11
12TRAD_SYNOPSIS
13 #include <string.h>
14 int memcmp(<[s1]>, <[s2]>, <[n]>)
15 void *<[s1]>;
16 void *<[s2]>;
17 size_t <[n]>;
18
19DESCRIPTION
20 This function compares not more than <[n]> characters of the
21 object pointed to by <[s1]> with the object pointed to by <[s2]>.
22
23
24RETURNS
25 The function returns an integer greater than, equal to or
26 less than zero according to whether the object pointed to by
27 <[s1]> is greater than, equal to or less than the object
28 pointed to by <[s2]>.
29
30PORTABILITY
31<<memcmp>> is ANSI C.
32
33<<memcmp>> requires no supporting OS subroutines.
34
35QUICKREF
36 memcmp ansi pure
37*/
38
39#include <string.h>
40
41
42/* Nonzero if either X or Y is not aligned on a "long" boundary. */
43#define UNALIGNED(X, Y) \
44 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
45
46/* How many bytes are copied each iteration of the word copy loop. */
47#define LBLOCKSIZE (sizeof (long))
48
49/* Threshhold for punting to the byte copier. */
50#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
51
52int
53_DEFUN (memcmp, (m1, m2, n),
54 _CONST _PTR m1 _AND
55 _CONST _PTR m2 _AND
56 size_t n)
57{
58#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
59 unsigned char *s1 = (unsigned char *) m1;
60 unsigned char *s2 = (unsigned char *) m2;
61
62 while (n--)
63 {
64 if (*s1 != *s2)
65 {
66 return *s1 - *s2;
67 }
68 s1++;
69 s2++;
70 }
71 return 0;
72#else
73 unsigned char *s1 = (unsigned char *) m1;
74 unsigned char *s2 = (unsigned char *) m2;
75 unsigned long *a1;
76 unsigned long *a2;
77
78 /* If the size is too small, or either pointer is unaligned,
79 then we punt to the byte compare loop. Hopefully this will
80 not turn up in inner loops. */
81 if (!TOO_SMALL(n) && !UNALIGNED(s1,s2))
82 {
83 /* Otherwise, load and compare the blocks of memory one
84 word at a time. */
85 a1 = (unsigned long*) s1;
86 a2 = (unsigned long*) s2;
87 while (n >= LBLOCKSIZE)
88 {
89 if (*a1 != *a2)
90 break;
91 a1++;
92 a2++;
93 n -= LBLOCKSIZE;
94 }
95
96 /* check m mod LBLOCKSIZE remaining characters */
97
98 s1 = (unsigned char*)a1;
99 s2 = (unsigned char*)a2;
100 }
101
102 while (n--)
103 {
104 if (*s1 != *s2)
105 return *s1 - *s2;
106 s1++;
107 s2++;
108 }
109
110 return 0;
111#endif /* not PREFER_SIZE_OVER_SPEED */
112}
113
diff --git a/firmware/libc/memcpy.c b/firmware/libc/memcpy.c
new file mode 100644
index 0000000000..a89ac3c557
--- /dev/null
+++ b/firmware/libc/memcpy.c
@@ -0,0 +1,117 @@
1/*
2FUNCTION
3 <<memcpy>>---copy memory regions
4
5ANSI_SYNOPSIS
6 #include <string.h>
7 void* memcpy(void *<[out]>, const void *<[in]>, size_t <[n]>);
8
9TRAD_SYNOPSIS
10 void *memcpy(<[out]>, <[in]>, <[n]>
11 void *<[out]>;
12 void *<[in]>;
13 size_t <[n]>;
14
15DESCRIPTION
16 This function copies <[n]> bytes from the memory region
17 pointed to by <[in]> to the memory region pointed to by
18 <[out]>.
19
20 If the regions overlap, the behavior is undefined.
21
22RETURNS
23 <<memcpy>> returns a pointer to the first byte of the <[out]>
24 region.
25
26PORTABILITY
27<<memcpy>> is ANSI C.
28
29<<memcpy>> requires no supporting OS subroutines.
30
31QUICKREF
32 memcpy ansi pure
33 */
34
35#include "config.h"
36#include <_ansi.h>
37#include <string.h>
38
39/* Nonzero if either X or Y is not aligned on a "long" boundary. */
40#define UNALIGNED(X, Y) \
41 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
42
43/* How many bytes are copied each iteration of the 4X unrolled loop. */
44#define BIGBLOCKSIZE (sizeof (long) << 2)
45
46/* How many bytes are copied each iteration of the word copy loop. */
47#define LITTLEBLOCKSIZE (sizeof (long))
48
49/* Threshold for punting to the byte copier. */
50#define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
51
52_PTR
53_DEFUN (memcpy, (dst0, src0, len0),
54 _PTR dst0 _AND
55 _CONST _PTR src0 _AND
56 size_t len0) ICODE_ATTR;
57
58_PTR
59_DEFUN (memcpy, (dst0, src0, len0),
60 _PTR dst0 _AND
61 _CONST _PTR src0 _AND
62 size_t len0)
63{
64#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
65 char *dst = (char *) dst0;
66 char *src = (char *) src0;
67
68 _PTR save = dst0;
69
70 while (len0--)
71 {
72 *dst++ = *src++;
73 }
74
75 return save;
76#else
77 char *dst = dst0;
78 _CONST char *src = src0;
79 long *aligned_dst;
80 _CONST long *aligned_src;
81 unsigned int len = len0;
82
83 /* If the size is small, or either SRC or DST is unaligned,
84 then punt into the byte copy loop. This should be rare. */
85 if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
86 {
87 aligned_dst = (long*)dst;
88 aligned_src = (long*)src;
89
90 /* Copy 4X long words at a time if possible. */
91 while (len >= BIGBLOCKSIZE)
92 {
93 *aligned_dst++ = *aligned_src++;
94 *aligned_dst++ = *aligned_src++;
95 *aligned_dst++ = *aligned_src++;
96 *aligned_dst++ = *aligned_src++;
97 len -= (unsigned int)BIGBLOCKSIZE;
98 }
99
100 /* Copy one long word at a time if possible. */
101 while (len >= LITTLEBLOCKSIZE)
102 {
103 *aligned_dst++ = *aligned_src++;
104 len -= LITTLEBLOCKSIZE;
105 }
106
107 /* Pick up any residual with a byte copier. */
108 dst = (char*)aligned_dst;
109 src = (char*)aligned_src;
110 }
111
112 while (len--)
113 *dst++ = *src++;
114
115 return dst0;
116#endif /* not PREFER_SIZE_OVER_SPEED */
117}
diff --git a/firmware/libc/memmove.c b/firmware/libc/memmove.c
new file mode 100644
index 0000000000..5f423964bb
--- /dev/null
+++ b/firmware/libc/memmove.c
@@ -0,0 +1,147 @@
1/*
2FUNCTION
3 <<memmove>>---move possibly overlapping memory
4
5INDEX
6 memmove
7
8ANSI_SYNOPSIS
9 #include <string.h>
10 void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
11
12TRAD_SYNOPSIS
13 #include <string.h>
14 void *memmove(<[dst]>, <[src]>, <[length]>)
15 void *<[dst]>;
16 void *<[src]>;
17 size_t <[length]>;
18
19DESCRIPTION
20 This function moves <[length]> characters from the block of
21 memory starting at <<*<[src]>>> to the memory starting at
22 <<*<[dst]>>>. <<memmove>> reproduces the characters correctly
23 at <<*<[dst]>>> even if the two areas overlap.
24
25
26RETURNS
27 The function returns <[dst]> as passed.
28
29PORTABILITY
30<<memmove>> is ANSI C.
31
32<<memmove>> requires no supporting OS subroutines.
33
34QUICKREF
35 memmove ansi pure
36*/
37
38#include "config.h"
39#include <_ansi.h>
40#include <string.h>
41
42/* Nonzero if either X or Y is not aligned on a "long" boundary. */
43#define UNALIGNED(X, Y) \
44 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
45
46/* How many bytes are copied each iteration of the 4X unrolled loop. */
47#define BIGBLOCKSIZE (sizeof (long) << 2)
48
49/* How many bytes are copied each iteration of the word copy loop. */
50#define LITTLEBLOCKSIZE (sizeof (long))
51
52/* Threshhold for punting to the byte copier. */
53#define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
54
55_PTR
56_DEFUN (memmove, (dst_void, src_void, length),
57 _PTR dst_void _AND
58 _CONST _PTR src_void _AND
59 size_t length) ICODE_ATTR;
60
61_PTR
62_DEFUN (memmove, (dst_void, src_void, length),
63 _PTR dst_void _AND
64 _CONST _PTR src_void _AND
65 size_t length)
66{
67#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
68 char *dst = dst_void;
69 _CONST char *src = src_void;
70
71 if (src < dst && dst < src + length)
72 {
73 /* Have to copy backwards */
74 src += length;
75 dst += length;
76 while (length--)
77 {
78 *--dst = *--src;
79 }
80 }
81 else
82 {
83 while (length--)
84 {
85 *dst++ = *src++;
86 }
87 }
88
89 return dst_void;
90#else
91 char *dst = dst_void;
92 _CONST char *src = src_void;
93 long *aligned_dst;
94 _CONST long *aligned_src;
95 unsigned int len = length;
96
97 if (src < dst && dst < src + len)
98 {
99 /* Destructive overlap...have to copy backwards */
100 src += len;
101 dst += len;
102 while (len--)
103 {
104 *--dst = *--src;
105 }
106 }
107 else
108 {
109 /* Use optimizing algorithm for a non-destructive copy to closely
110 match memcpy. If the size is small or either SRC or DST is unaligned,
111 then punt into the byte copy loop. This should be rare. */
112 if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
113 {
114 aligned_dst = (long*)dst;
115 aligned_src = (long*)src;
116
117 /* Copy 4X long words at a time if possible. */
118 while (len >= BIGBLOCKSIZE)
119 {
120 *aligned_dst++ = *aligned_src++;
121 *aligned_dst++ = *aligned_src++;
122 *aligned_dst++ = *aligned_src++;
123 *aligned_dst++ = *aligned_src++;
124 len -= BIGBLOCKSIZE;
125 }
126
127 /* Copy one long word at a time if possible. */
128 while (len >= LITTLEBLOCKSIZE)
129 {
130 *aligned_dst++ = *aligned_src++;
131 len -= LITTLEBLOCKSIZE;
132 }
133
134 /* Pick up any residual with a byte copier. */
135 dst = (char*)aligned_dst;
136 src = (char*)aligned_src;
137 }
138
139 while (len--)
140 {
141 *dst++ = *src++;
142 }
143 }
144
145 return dst_void;
146#endif /* not PREFER_SIZE_OVER_SPEED */
147}
diff --git a/firmware/libc/memset.c b/firmware/libc/memset.c
new file mode 100644
index 0000000000..7b8d2137e8
--- /dev/null
+++ b/firmware/libc/memset.c
@@ -0,0 +1,110 @@
1/*
2FUNCTION
3 <<memset>>---set an area of memory
4
5INDEX
6 memset
7
8ANSI_SYNOPSIS
9 #include <string.h>
10 void *memset(const void *<[dst]>, int <[c]>, size_t <[length]>);
11
12TRAD_SYNOPSIS
13 #include <string.h>
14 void *memset(<[dst]>, <[c]>, <[length]>)
15 void *<[dst]>;
16 int <[c]>;
17 size_t <[length]>;
18
19DESCRIPTION
20 This function converts the argument <[c]> into an unsigned
21 char and fills the first <[length]> characters of the array
22 pointed to by <[dst]> to the value.
23
24RETURNS
25 <<memset>> returns the value of <[m]>.
26
27PORTABILITY
28<<memset>> is ANSI C.
29
30 <<memset>> requires no supporting OS subroutines.
31
32QUICKREF
33 memset ansi pure
34*/
35
36#include <string.h>
37#include "_ansi.h"
38
39#define LBLOCKSIZE (sizeof(long))
40#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
41#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
42
43_PTR
44_DEFUN (memset, (m, c, n),
45 _PTR m _AND
46 int c _AND
47 size_t n)
48{
49#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
50 char *s = (char *) m;
51
52 while (n-- != 0)
53 {
54 *s++ = (char) c;
55 }
56
57 return m;
58#else
59 char *s = (char *) m;
60 unsigned int i;
61 unsigned long buffer;
62 unsigned long *aligned_addr;
63
64 if (!TOO_SMALL (n) && !UNALIGNED (m))
65 {
66 /* If we get this far, we know that n is large and m is word-aligned. */
67
68 aligned_addr = (unsigned long*)m;
69
70 /* Store C into each char sized location in BUFFER so that
71 we can set large blocks quickly. */
72 c &= 0xff;
73 if (LBLOCKSIZE == 4)
74 {
75 buffer = (c << 8) | c;
76 buffer |= (buffer << 16);
77 }
78 else
79 {
80 buffer = 0;
81 for (i = 0; i < LBLOCKSIZE; i++)
82 buffer = (buffer << 8) | c;
83 }
84
85 while (n >= LBLOCKSIZE*4)
86 {
87 *aligned_addr++ = buffer;
88 *aligned_addr++ = buffer;
89 *aligned_addr++ = buffer;
90 *aligned_addr++ = buffer;
91 n -= 4*LBLOCKSIZE;
92 }
93
94 while (n >= LBLOCKSIZE)
95 {
96 *aligned_addr++ = buffer;
97 n -= LBLOCKSIZE;
98 }
99 /* Pick up the remainder with a bytewise loop. */
100 s = (char*)aligned_addr;
101 }
102
103 while (n--)
104 {
105 *s++ = (char)c;
106 }
107
108 return m;
109#endif /* not PREFER_SIZE_OVER_SPEED */
110}
diff --git a/firmware/libc/mktime.c b/firmware/libc/mktime.c
new file mode 100644
index 0000000000..a52381ede5
--- /dev/null
+++ b/firmware/libc/mktime.c
@@ -0,0 +1,61 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22
23#include <time.h>
24#include "config.h"
25
26#if CONFIG_RTC
27/* mktime() code taken from lynx-2.8.5 source, written
28 by Philippe De Muyter <phdm@macqel.be> */
29time_t mktime(struct tm *t)
30{
31 short month, year;
32 time_t result;
33 static int m_to_d[12] =
34 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
35
36 month = t->tm_mon;
37 year = t->tm_year + month / 12 + 1900;
38 month %= 12;
39 if (month < 0)
40 {
41 year -= 1;
42 month += 12;
43 }
44 result = (year - 1970) * 365 + (year - 1969) / 4 + m_to_d[month];
45 result = (year - 1970) * 365 + m_to_d[month];
46 if (month <= 1)
47 year -= 1;
48 result += (year - 1968) / 4;
49 result -= (year - 1900) / 100;
50 result += (year - 1600) / 400;
51 result += t->tm_mday;
52 result -= 1;
53 result *= 24;
54 result += t->tm_hour;
55 result *= 60;
56 result += t->tm_min;
57 result *= 60;
58 result += t->tm_sec;
59 return(result);
60}
61#endif
diff --git a/firmware/libc/qsort.c b/firmware/libc/qsort.c
new file mode 100644
index 0000000000..8c4d1ad511
--- /dev/null
+++ b/firmware/libc/qsort.c
@@ -0,0 +1,222 @@
1/*
2FUNCTION
3<<qsort>>---sort an array
4
5INDEX
6 qsort
7
8ANSI_SYNOPSIS
9 #include <stdlib.h>
10 void qsort(void *<[base]>, size_t <[nmemb]>, size_t <[size]>,
11 int (*<[compar]>)(const void *, const void *) );
12
13TRAD_SYNOPSIS
14 #include <stdlib.h>
15 qsort(<[base]>, <[nmemb]>, <[size]>, <[compar]> )
16 char *<[base]>;
17 size_t <[nmemb]>;
18 size_t <[size]>;
19 int (*<[compar]>)();
20
21DESCRIPTION
22<<qsort>> sorts an array (beginning at <[base]>) of <[nmemb]> objects.
23<[size]> describes the size of each element of the array.
24
25You must supply a pointer to a comparison function, using the argument
26shown as <[compar]>. (This permits sorting objects of unknown
27properties.) Define the comparison function to accept two arguments,
28each a pointer to an element of the array starting at <[base]>. The
29result of <<(*<[compar]>)>> must be negative if the first argument is
30less than the second, zero if the two arguments match, and positive if
31the first argument is greater than the second (where ``less than'' and
32``greater than'' refer to whatever arbitrary ordering is appropriate).
33
34The array is sorted in place; that is, when <<qsort>> returns, the
35array elements beginning at <[base]> have been reordered.
36
37RETURNS
38<<qsort>> does not return a result.
39
40PORTABILITY
41<<qsort>> is required by ANSI (without specifying the sorting algorithm).
42*/
43
44/*-
45 * Copyright (c) 1992, 1993
46 * The Regents of the University of California. All rights reserved.
47 *
48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions
50 * are met:
51 * 1. Redistributions of source code must retain the above copyright
52 * notice, this list of conditions and the following disclaimer.
53 * 2. Redistributions in binary form must reproduce the above copyright
54 * notice, this list of conditions and the following disclaimer in the
55 * documentation and/or other materials provided with the distribution.
56 * 3. All advertising materials mentioning features or use of this software
57 * must display the following acknowledgement:
58 * This product includes software developed by the University of
59 * California, Berkeley and its contributors.
60 * 4. Neither the name of the University nor the names of its contributors
61 * may be used to endorse or promote products derived from this software
62 * without specific prior written permission.
63 *
64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * SUCH DAMAGE.
75 */
76
77#include <_ansi.h>
78#include <stdlib.h>
79
80#ifndef __GNUC__
81#define inline
82#endif
83
84static inline char *med3 _PARAMS((char *, char *, char *, int (*cmp)(const _PTR,const _PTR)));
85static inline void swapfunc _PARAMS((char *, char *, int, int));
86
87#define min(a, b) (a) < (b) ? a : b
88
89/*
90 * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
91 */
92#define swapcode(TYPE, parmi, parmj, n) { \
93 long i = (n) / sizeof (TYPE); \
94 register TYPE *pi = (TYPE *) (parmi); \
95 register TYPE *pj = (TYPE *) (parmj); \
96 do { \
97 register TYPE t = *pi; \
98 *pi++ = *pj; \
99 *pj++ = t; \
100 } while (--i > 0); \
101}
102
103#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
104 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
105
106static inline void
107_DEFUN(swapfunc, (a, b, n, swaptype),
108 char *a _AND
109 char *b _AND
110 int n _AND
111 int swaptype)
112{
113 if(swaptype <= 1)
114 swapcode(long, a, b, n)
115 else
116 swapcode(char, a, b, n)
117}
118
119#define swap(a, b) \
120 if (swaptype == 0) { \
121 long t = *(long *)(a); \
122 *(long *)(a) = *(long *)(b); \
123 *(long *)(b) = t; \
124 } else \
125 swapfunc(a, b, es, swaptype)
126
127#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
128
129static inline char *
130_DEFUN(med3, (a, b, c, cmp),
131 char *a _AND
132 char *b _AND
133 char *c _AND
134 int (*cmp)(const _PTR,const _PTR))
135{
136 return cmp(a, b) < 0 ?
137 (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
138 :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
139}
140
141void
142_DEFUN(qsort, (a, n, es, cmp),
143 void *a _AND
144 size_t n _AND
145 size_t es _AND
146 int (*cmp)(const _PTR,const _PTR))
147{
148 char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
149 int d, r, swaptype, swap_cnt;
150
151loop: SWAPINIT(a, es);
152 swap_cnt = 0;
153 if (n < 7) {
154 for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
155 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
156 pl -= es)
157 swap(pl, pl - es);
158 return;
159 }
160 pm = (char *) a + (n / 2) * es;
161 if (n > 7) {
162 pl = a;
163 pn = (char *) a + (n - 1) * es;
164 if (n > 40) {
165 d = (n / 8) * es;
166 pl = med3(pl, pl + d, pl + 2 * d, cmp);
167 pm = med3(pm - d, pm, pm + d, cmp);
168 pn = med3(pn - 2 * d, pn - d, pn, cmp);
169 }
170 pm = med3(pl, pm, pn, cmp);
171 }
172 swap(a, pm);
173 pa = pb = (char *) a + es;
174
175 pc = pd = (char *) a + (n - 1) * es;
176 for (;;) {
177 while (pb <= pc && (r = cmp(pb, a)) <= 0) {
178 if (r == 0) {
179 swap_cnt = 1;
180 swap(pa, pb);
181 pa += es;
182 }
183 pb += es;
184 }
185 while (pb <= pc && (r = cmp(pc, a)) >= 0) {
186 if (r == 0) {
187 swap_cnt = 1;
188 swap(pc, pd);
189 pd -= es;
190 }
191 pc -= es;
192 }
193 if (pb > pc)
194 break;
195 swap(pb, pc);
196 swap_cnt = 1;
197 pb += es;
198 pc -= es;
199 }
200 if (swap_cnt == 0) { /* Switch to insertion sort */
201 for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
202 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
203 pl -= es)
204 swap(pl, pl - es);
205 return;
206 }
207
208 pn = (char *) a + n * es;
209 r = min(pa - (char *)a, pb - pa);
210 vecswap(a, pb - r, r);
211 r = min((unsigned int)(pd - pc), pn - pd - es);
212 vecswap(pb, pn - r, r);
213 if ((unsigned int)(r = pb - pa) > es)
214 qsort(a, r / es, es, cmp);
215 if ((unsigned int)(r = pd - pc) > es) {
216 /* Iterate rather than recurse to save stack space */
217 a = pn - r;
218 n = r / es;
219 goto loop;
220 }
221/* qsort(pn - r, r / es, es, cmp);*/
222}
diff --git a/firmware/libc/random.c b/firmware/libc/random.c
new file mode 100644
index 0000000000..f3efe89351
--- /dev/null
+++ b/firmware/libc/random.c
@@ -0,0 +1,119 @@
1/*
2 A C-program for MT19937, with initialization improved 2002/2/10.
3 Coded by Takuji Nishimura and Makoto Matsumoto.
4 This is a faster version by taking Shawn Cokus's optimization,
5 Matthe Bellew's simplification.
6
7 Before using, initialize the state by using srand(seed).
8
9 Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
10 All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
15
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
18
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
22
23 3. The names of its contributors may not be used to endorse or promote
24 products derived from this software without specific prior written
25 permission.
26
27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
31 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39 Any feedback is very welcome.
40 http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
41 email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
42*/
43
44/*
45 Adapted to Rockbox by Jens Arnold
46*/
47
48#include <stdlib.h>
49
50/* Period parameters */
51#define N 624
52#define M 397
53#define MATRIX_A 0x9908b0dfUL /* constant vector a */
54#define UMASK 0x80000000UL /* most significant w-r bits */
55#define LMASK 0x7fffffffUL /* least significant r bits */
56#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
57#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
58
59static unsigned long state[N]; /* the array for the state vector */
60static int left = 0;
61static unsigned long *next;
62
63/* initializes state[N] with a seed */
64void srand(unsigned int seed)
65{
66 unsigned long x = seed & 0xffffffffUL;
67 unsigned long *s = state;
68 int j;
69
70 for (*s++ = x, j = 1; j < N; j++) {
71 x = (1812433253UL * (x ^ (x >> 30)) + j) & 0xffffffffUL;
72 *s++ = x;
73 /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
74 /* In the previous versions, MSBs of the seed affect */
75 /* only MSBs of the array state[]. */
76 /* 2002/01/09 modified by Makoto Matsumoto */
77 }
78 left = 1;
79}
80
81static void next_state(void)
82{
83 unsigned long *p = state;
84 int j;
85
86 /* if srand() has not been called, */
87 /* a default initial seed is used */
88 if (left < 0)
89 srand(5489UL);
90
91 left = N;
92 next = state;
93
94 for (j = N - M + 1; --j; p++)
95 *p = p[M] ^ TWIST(p[0], p[1]);
96
97 for (j = M; --j; p++)
98 *p = p[M-N] ^ TWIST(p[0], p[1]);
99
100 *p = p[M-N] ^ TWIST(p[0], state[0]);
101}
102
103/* generates a random number on [0,RAND_MAX]-interval */
104int rand(void)
105{
106 unsigned long y;
107
108 if (--left <= 0)
109 next_state();
110 y = *next++;
111
112 /* Tempering */
113 y ^= (y >> 11);
114 y ^= (y << 7) & 0x9d2c5680UL;
115 y ^= (y << 15) & 0xefc60000UL;
116 y ^= (y >> 18);
117
118 return ((unsigned int)y) >> 1;
119}
diff --git a/firmware/libc/sprintf.c b/firmware/libc/sprintf.c
new file mode 100644
index 0000000000..b02f5a2fae
--- /dev/null
+++ b/firmware/libc/sprintf.c
@@ -0,0 +1,93 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Gary Czvitkovicz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22/*
23 * Minimal printf and snprintf formatting functions
24 *
25 * These support %c %s %d and %x
26 * Field width and zero-padding flag only
27 */
28
29#include <stdio.h>
30#include <stdarg.h>
31#include <stdbool.h>
32#include <limits.h>
33#include "format.h"
34
35/* ALSA library requires a more advanced snprintf, so let's not
36 override it in simulator for Linux. Note that Cygwin requires
37 our snprintf or it produces garbled output after a while. */
38
39struct for_snprintf {
40 unsigned char *ptr; /* where to store it */
41 size_t bytes; /* amount already stored */
42 size_t max; /* max amount to store */
43};
44
45static int sprfunc(void *ptr, unsigned char letter)
46{
47 struct for_snprintf *pr = (struct for_snprintf *)ptr;
48 if(pr->bytes < pr->max) {
49 *pr->ptr = letter;
50 pr->ptr++;
51 pr->bytes++;
52 return true;
53 }
54 return false; /* filled buffer */
55}
56
57
58int snprintf(char *buf, size_t size, const char *fmt, ...)
59{
60 bool ok;
61 va_list ap;
62 struct for_snprintf pr;
63
64 pr.ptr = (unsigned char *)buf;
65 pr.bytes = 0;
66 pr.max = size;
67
68 va_start(ap, fmt);
69 ok = format(sprfunc, &pr, fmt, ap);
70 va_end(ap);
71
72 /* make sure it ends with a trailing zero */
73 pr.ptr[(pr.bytes < pr.max) ? 0 : -1] = '\0';
74
75 return pr.bytes;
76}
77
78int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
79{
80 bool ok;
81 struct for_snprintf pr;
82
83 pr.ptr = (unsigned char *)buf;
84 pr.bytes = 0;
85 pr.max = size;
86
87 ok = format(sprfunc, &pr, fmt, ap);
88
89 /* make sure it ends with a trailing zero */
90 pr.ptr[(pr.bytes < pr.max) ? 0 : -1] = '\0';
91
92 return pr.bytes;
93}
diff --git a/firmware/libc/sscanf.c b/firmware/libc/sscanf.c
new file mode 100644
index 0000000000..5fbe81f3e0
--- /dev/null
+++ b/firmware/libc/sscanf.c
@@ -0,0 +1,282 @@
1#include <stdarg.h>
2#include <string.h>
3#include <stdbool.h>
4
5static inline bool isspace(char c)
6{
7 return (c == ' ') || (c == '\t') || (c == '\n');
8}
9
10static inline bool isdigit(char c)
11{
12 return (c >= '0') && (c <= '9');
13}
14
15static inline bool isxdigit(char c)
16{
17 return ((c >= '0') && (c <= '9'))
18 || ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F'));
19}
20
21static int parse_dec(int (*peek)(void *userp),
22 void (*pop)(void *userp),
23 void *userp,
24 long *vp)
25{
26 long v = 0;
27 int n = 0;
28 int minus = 0;
29 char ch;
30
31 if ((*peek)(userp) == '-')
32 {
33 (*pop)(userp);
34 n++;
35 minus = 1;
36 }
37
38 ch = (*peek)(userp);
39 if (!isdigit(ch))
40 return -1;
41
42 do
43 {
44 v = v * 10 + ch - '0';
45 (*pop)(userp);
46 n++;
47 ch = (*peek)(userp);
48 } while (isdigit(ch));
49
50 *vp = minus ? -v : v;
51 return n;
52}
53
54static int parse_chars(int (*peek)(void *userp),
55 void (*pop)(void *userp),
56 void *userp,
57 char *vp,
58 bool fake)
59{
60 int n = 0;
61
62 char *pt=vp;
63
64 while (!isspace((*peek)(userp)))
65 {
66 if(fake==false)
67 *(pt++) = (*peek)(userp);
68
69 n++;
70 (*pop)(userp);
71 }
72
73 if(fake==false)
74 (*pt)='\0';
75
76 return n;
77}
78
79static int parse_hex(int (*peek)(void *userp),
80 void (*pop)(void *userp),
81 void *userp,
82 unsigned long *vp)
83{
84 unsigned long v = 0;
85 int n = 0;
86 char ch;
87
88 ch = (*peek)(userp);
89 if (!isxdigit(ch))
90 return -1;
91
92 do
93 {
94 if (ch >= 'a')
95 ch = ch - 'a' + 10;
96 else if (ch >= 'A')
97 ch = ch - 'A' + 10;
98 else
99 ch = ch - '0';
100 v = v * 16 + ch;
101 (*pop)(userp);
102 n++;
103 ch = (*peek)(userp);
104 } while (isxdigit(ch));
105
106 *vp = v;
107 return n;
108}
109
110static int skip_spaces(int (*peek)(void *userp),
111 void (*pop)(void *userp),
112 void *userp)
113{
114 int n = 0;
115 while (isspace((*peek)(userp))) {
116 n++;
117 (*pop)(userp);
118 }
119 return n;
120}
121
122static int scan(int (*peek)(void *userp),
123 void (*pop)(void *userp),
124 void *userp,
125 const char *fmt,
126 va_list ap)
127{
128 char ch;
129 int n = 0;
130 int n_chars = 0;
131 int r;
132 long lval;
133 bool skip=false;
134 unsigned long ulval;
135
136 while ((ch = *fmt++) != '\0')
137 {
138 bool literal = false;
139
140 if (ch == '%')
141 {
142 ch = *fmt++;
143
144 if(ch== '*') /* We should process this, but not store it in an arguement */
145 {
146 ch=*fmt++;
147 skip=true;
148 }
149 else
150 {
151 skip=false;
152 }
153
154 switch (ch)
155 {
156 case 'x':
157 n_chars += skip_spaces(peek, pop, userp);
158 if ((r = parse_hex(peek, pop, userp, &ulval)) >= 0)
159 {
160 if(skip==false)
161 {
162 *(va_arg(ap, unsigned int *)) = ulval;
163 n++;
164 }
165 n_chars += r;
166 }
167 else
168 return n;
169 break;
170 case 'd':
171 n_chars += skip_spaces(peek, pop, userp);
172 if ((r = parse_dec(peek, pop, userp, &lval)) >= 0)
173 {
174 if(skip==false)
175 {
176 *(va_arg(ap, int *)) = lval;
177 n++;
178 }
179 n_chars += r;
180 }
181 else
182 return n;
183 break;
184 case 'n':
185 if(skip==false)
186 {
187 *(va_arg(ap, int *)) = n_chars;
188 n++;
189 }
190 break;
191 case 'l':
192 n_chars += skip_spaces(peek, pop, userp);
193 ch = *fmt++;
194 switch (ch)
195 {
196 case 'x':
197 if ((r = parse_hex(peek, pop, userp, &ulval)) >= 0)
198 {
199 if(skip==false)
200 {
201 *(va_arg(ap, unsigned long *)) = ulval;
202 n++;
203 }
204 n_chars += r;
205 }
206 else
207 return n;
208 break;
209 case 'd':
210 if ((r = parse_dec(peek, pop, userp, &lval)) >= 0)
211 {
212 if(skip==false)
213 {
214 *(va_arg(ap, long *)) = lval;
215 n++;
216 }
217 n_chars += r;
218 }
219 else
220 return n;
221 break;
222 case '\0':
223 return n;
224 default:
225 literal = true;
226 break;
227 }
228 break;
229 case 's':
230 n_chars += skip_spaces(peek, pop, userp);
231 n_chars += parse_chars(peek,pop, userp,skip?0:va_arg(ap, char *), skip );
232 if(skip==false)
233 {
234 n++;
235 }
236 break;
237 case '\0':
238 return n;
239 default:
240 literal = true;
241 break;
242 }
243 } else
244 literal = true;
245
246 if (literal)
247 {
248 n_chars += skip_spaces(peek, pop, userp);
249 if ((*peek)(userp) != ch)
250 continue;
251 else
252 {
253 (*pop)(userp);
254 n_chars++;
255 }
256 }
257 }
258 return n;
259}
260
261static int sspeek(void *userp)
262{
263 return **((char **)userp);
264}
265
266static void sspop(void *userp)
267{
268 (*((char **)userp))++;
269}
270
271int sscanf(const char *s, const char *fmt, ...)
272{
273 int r;
274 va_list ap;
275 const char *p;
276
277 p = s;
278 va_start(ap, fmt);
279 r = scan(sspeek, sspop, &p, fmt, ap);
280 va_end(ap);
281 return r;
282}
diff --git a/firmware/libc/strcat.c b/firmware/libc/strcat.c
new file mode 100644
index 0000000000..221529519c
--- /dev/null
+++ b/firmware/libc/strcat.c
@@ -0,0 +1,14 @@
1#include <string.h>
2
3char *strcat(char *s1,
4 const char *s2)
5{
6 char *s = s1;
7
8 while (*s1)
9 s1++;
10
11 while ((*s1++ = *s2++))
12 ;
13 return s;
14}
diff --git a/firmware/libc/strchr.c b/firmware/libc/strchr.c
new file mode 100644
index 0000000000..96acf5edf6
--- /dev/null
+++ b/firmware/libc/strchr.c
@@ -0,0 +1,108 @@
1/*
2FUNCTION
3 <<strchr>>---search for character in string
4
5INDEX
6 strchr
7
8ANSI_SYNOPSIS
9 #include <string.h>
10 char * strchr(const char *<[string]>, int <[c]>);
11
12TRAD_SYNOPSIS
13 #include <string.h>
14 char * strchr(<[string]>, <[c]>);
15 char *<[string]>;
16 int *<[c]>;
17
18DESCRIPTION
19 This function finds the first occurence of <[c]> (converted to
20 a char) in the string pointed to by <[string]> (including the
21 terminating null character).
22
23RETURNS
24 Returns a pointer to the located character, or a null pointer
25 if <[c]> does not occur in <[string]>.
26
27PORTABILITY
28<<strchr>> is ANSI C.
29
30<<strchr>> requires no supporting OS subroutines.
31
32QUICKREF
33 strchr ansi pure
34*/
35
36#include <string.h>
37#include <limits.h>
38
39/* Nonzero if X is not aligned on a "long" boundary. */
40#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
41
42/* How many bytes are loaded each iteration of the word copy loop. */
43#define LBLOCKSIZE (sizeof (long))
44
45#if LONG_MAX == 2147483647L
46#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
47#else
48#if LONG_MAX == 9223372036854775807L
49/* Nonzero if X (a long int) contains a NULL byte. */
50#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
51#else
52#error long int is not a 32bit or 64bit type.
53#endif
54#endif
55
56/* DETECTCHAR returns nonzero if (long)X contains the byte used
57 to fill (long)MASK. */
58#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK))
59
60char *
61_DEFUN (strchr, (s1, i),
62 _CONST char *s1 _AND
63 int i)
64{
65 _CONST unsigned char *s = (_CONST unsigned char *)s1;
66#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
67 unsigned char c = (unsigned int)i;
68
69 while (*s && *s != c)
70 {
71 s++;
72 }
73
74 if (*s != c)
75 {
76 s = NULL;
77 }
78
79 return (char *) s;
80#else
81 unsigned char c = (unsigned char)i;
82 unsigned long mask,j;
83 unsigned long *aligned_addr;
84
85 if (!UNALIGNED (s))
86 {
87 mask = 0;
88 for (j = 0; j < LBLOCKSIZE; j++)
89 mask = (mask << 8) | c;
90
91 aligned_addr = (unsigned long*)s;
92 while (!DETECTNULL (*aligned_addr) && !DETECTCHAR (*aligned_addr, mask))
93 aligned_addr++;
94
95 /* The block of bytes currently pointed to by aligned_addr
96 contains either a null or the target char, or both. We
97 catch it using the bytewise search. */
98
99 s = (unsigned char*)aligned_addr;
100 }
101
102 while (*s && *s != c)
103 s++;
104 if (*s == c)
105 return (char *)s;
106 return NULL;
107#endif /* not PREFER_SIZE_OVER_SPEED */
108}
diff --git a/firmware/libc/strcmp.c b/firmware/libc/strcmp.c
new file mode 100644
index 0000000000..bbbf4b174a
--- /dev/null
+++ b/firmware/libc/strcmp.c
@@ -0,0 +1,106 @@
1/*
2FUNCTION
3 <<strcmp>>---character string compare
4
5INDEX
6 strcmp
7
8ANSI_SYNOPSIS
9 #include <string.h>
10 int strcmp(const char *<[a]>, const char *<[b]>);
11
12TRAD_SYNOPSIS
13 #include <string.h>
14 int strcmp(<[a]>, <[b]>)
15 char *<[a]>;
16 char *<[b]>;
17
18DESCRIPTION
19 <<strcmp>> compares the string at <[a]> to
20 the string at <[b]>.
21
22RETURNS
23 If <<*<[a]>>> sorts lexicographically after <<*<[b]>>>,
24 <<strcmp>> returns a number greater than zero. If the two
25 strings match, <<strcmp>> returns zero. If <<*<[a]>>>
26 sorts lexicographically before <<*<[b]>>>, <<strcmp>> returns a
27 number less than zero.
28
29PORTABILITY
30<<strcmp>> is ANSI C.
31
32<<strcmp>> requires no supporting OS subroutines.
33
34QUICKREF
35 strcmp ansi pure
36*/
37
38#include <string.h>
39#include <limits.h>
40
41/* Nonzero if either X or Y is not aligned on a "long" boundary. */
42#define UNALIGNED(X, Y) \
43 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
44
45/* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
46#if LONG_MAX == 2147483647L
47#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
48#else
49#if LONG_MAX == 9223372036854775807L
50#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
51#else
52#error long int is not a 32bit or 64bit type.
53#endif
54#endif
55
56#ifndef DETECTNULL
57#error long int is not a 32bit or 64bit byte
58#endif
59
60int
61_DEFUN (strcmp, (s1, s2),
62 _CONST char *s1 _AND
63 _CONST char *s2)
64{
65#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
66 while (*s1 != '\0' && *s1 == *s2)
67 {
68 s1++;
69 s2++;
70 }
71
72 return (*(unsigned char *) s1) - (*(unsigned char *) s2);
73#else
74 unsigned long *a1;
75 unsigned long *a2;
76
77 /* If s1 or s2 are unaligned, then compare bytes. */
78 if (!UNALIGNED (s1, s2))
79 {
80 /* If s1 and s2 are word-aligned, compare them a word at a time. */
81 a1 = (unsigned long*)s1;
82 a2 = (unsigned long*)s2;
83 while (*a1 == *a2)
84 {
85 /* To get here, *a1 == *a2, thus if we find a null in *a1,
86 then the strings must be equal, so return zero. */
87 if (DETECTNULL (*a1))
88 return 0;
89
90 a1++;
91 a2++;
92 }
93
94 /* A difference was detected in last few bytes of s1, so search bytewise */
95 s1 = (char*)a1;
96 s2 = (char*)a2;
97 }
98
99 while (*s1 != '\0' && *s1 == *s2)
100 {
101 s1++;
102 s2++;
103 }
104 return (*(unsigned char *) s1) - (*(unsigned char *) s2);
105#endif /* not PREFER_SIZE_OVER_SPEED */
106}
diff --git a/firmware/libc/strcpy.c b/firmware/libc/strcpy.c
new file mode 100644
index 0000000000..077ae73cc6
--- /dev/null
+++ b/firmware/libc/strcpy.c
@@ -0,0 +1,99 @@
1/*
2FUNCTION
3 <<strcpy>>---copy string
4
5INDEX
6 strcpy
7
8ANSI_SYNOPSIS
9 #include <string.h>
10 char *strcpy(char *<[dst]>, const char *<[src]>);
11
12TRAD_SYNOPSIS
13 #include <string.h>
14 char *strcpy(<[dst]>, <[src]>)
15 char *<[dst]>;
16 char *<[src]>;
17
18DESCRIPTION
19 <<strcpy>> copies the string pointed to by <[src]>
20 (including the terminating null character) to the array
21 pointed to by <[dst]>.
22
23RETURNS
24 This function returns the initial value of <[dst]>.
25
26PORTABILITY
27<<strcpy>> is ANSI C.
28
29<<strcpy>> requires no supporting OS subroutines.
30
31QUICKREF
32 strcpy ansi pure
33*/
34
35#include <string.h>
36#include <limits.h>
37
38/*SUPPRESS 560*/
39/*SUPPRESS 530*/
40
41/* Nonzero if either X or Y is not aligned on a "long" boundary. */
42#define UNALIGNED(X, Y) \
43 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
44
45#if LONG_MAX == 2147483647L
46#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
47#else
48#if LONG_MAX == 9223372036854775807L
49/* Nonzero if X (a long int) contains a NULL byte. */
50#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
51#else
52#error long int is not a 32bit or 64bit type.
53#endif
54#endif
55
56#ifndef DETECTNULL
57#error long int is not a 32bit or 64bit byte
58#endif
59
60char*
61_DEFUN (strcpy, (dst0, src0),
62 char *dst0 _AND
63 _CONST char *src0)
64{
65#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
66 char *s = dst0;
67
68 while ((*dst0++ = *src0++))
69 ;
70
71 return s;
72#else
73 char *dst = dst0;
74 _CONST char *src = src0;
75 long *aligned_dst;
76 _CONST long *aligned_src;
77
78 /* If SRC or DEST is unaligned, then copy bytes. */
79 if (!UNALIGNED (src, dst))
80 {
81 aligned_dst = (long*)dst;
82 aligned_src = (long*)src;
83
84 /* SRC and DEST are both "long int" aligned, try to do "long int"
85 sized copies. */
86 while (!DETECTNULL(*aligned_src))
87 {
88 *aligned_dst++ = *aligned_src++;
89 }
90
91 dst = (char*)aligned_dst;
92 src = (char*)aligned_src;
93 }
94
95 while ((*dst++ = *src++))
96 ;
97 return dst0;
98#endif /* not PREFER_SIZE_OVER_SPEED */
99}
diff --git a/firmware/libc/strlen.c b/firmware/libc/strlen.c
new file mode 100644
index 0000000000..4d33eafce6
--- /dev/null
+++ b/firmware/libc/strlen.c
@@ -0,0 +1,93 @@
1/*
2FUNCTION
3 <<strlen>>---character string length
4
5INDEX
6 strlen
7
8ANSI_SYNOPSIS
9 #include <string.h>
10 size_t strlen(const char *<[str]>);
11
12TRAD_SYNOPSIS
13 #include <string.h>
14 size_t strlen(<[str]>)
15 char *<[src]>;
16
17DESCRIPTION
18 The <<strlen>> function works out the length of the string
19 starting at <<*<[str]>>> by counting chararacters until it
20 reaches a <<NULL>> character.
21
22RETURNS
23 <<strlen>> returns the character count.
24
25PORTABILITY
26<<strlen>> is ANSI C.
27
28<<strlen>> requires no supporting OS subroutines.
29
30QUICKREF
31 strlen ansi pure
32*/
33
34#include "config.h"
35#include <_ansi.h>
36#include <string.h>
37#include <limits.h>
38
39#define LBLOCKSIZE (sizeof (long))
40#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
41
42#if LONG_MAX == 2147483647L
43#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
44#else
45#if LONG_MAX == 9223372036854775807L
46/* Nonzero if X (a long int) contains a NULL byte. */
47#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
48#else
49#error long int is not a 32bit or 64bit type.
50#endif
51#endif
52
53#ifndef DETECTNULL
54#error long int is not a 32bit or 64bit byte
55#endif
56
57size_t
58_DEFUN (strlen, (str),
59 _CONST char *str) ICODE_ATTR;
60
61size_t
62_DEFUN (strlen, (str),
63 _CONST char *str)
64{
65#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
66 _CONST char *start = str;
67
68 while (*str)
69 str++;
70
71 return str - start;
72#else
73 _CONST char *start = str;
74 unsigned long *aligned_addr;
75
76 if (!UNALIGNED (str))
77 {
78 /* If the string is word-aligned, we can check for the presence of
79 a null in each word-sized block. */
80 aligned_addr = (unsigned long*)str;
81 while (!DETECTNULL (*aligned_addr))
82 aligned_addr++;
83
84 /* Once a null is detected, we check each byte in that block for a
85 precise position of the null. */
86 str = (char*)aligned_addr;
87 }
88
89 while (*str)
90 str++;
91 return str - start;
92#endif /* not PREFER_SIZE_OVER_SPEED */
93}
diff --git a/firmware/libc/strncmp.c b/firmware/libc/strncmp.c
new file mode 100644
index 0000000000..b1d8d9d43a
--- /dev/null
+++ b/firmware/libc/strncmp.c
@@ -0,0 +1,122 @@
1/*
2FUNCTION
3 <<strncmp>>---character string compare
4
5INDEX
6 strncmp
7
8ANSI_SYNOPSIS
9 #include <string.h>
10 int strncmp(const char *<[a]>, const char * <[b]>, size_t <[length]>);
11
12TRAD_SYNOPSIS
13 #include <string.h>
14 int strncmp(<[a]>, <[b]>, <[length]>)
15 char *<[a]>;
16 char *<[b]>;
17 size_t <[length]>
18
19DESCRIPTION
20 <<strncmp>> compares up to <[length]> characters
21 from the string at <[a]> to the string at <[b]>.
22
23RETURNS
24 If <<*<[a]>>> sorts lexicographically after <<*<[b]>>>,
25 <<strncmp>> returns a number greater than zero. If the two
26 strings are equivalent, <<strncmp>> returns zero. If <<*<[a]>>>
27 sorts lexicographically before <<*<[b]>>>, <<strncmp>> returns a
28 number less than zero.
29
30PORTABILITY
31<<strncmp>> is ANSI C.
32
33<<strncmp>> requires no supporting OS subroutines.
34
35QUICKREF
36 strncmp ansi pure
37*/
38
39#include <string.h>
40#include <limits.h>
41
42/* Nonzero if either X or Y is not aligned on a "long" boundary. */
43#define UNALIGNED(X, Y) \
44 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
45
46/* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
47#if LONG_MAX == 2147483647L
48#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
49#else
50#if LONG_MAX == 9223372036854775807L
51#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
52#else
53#error long int is not a 32bit or 64bit type.
54#endif
55#endif
56
57#ifndef DETECTNULL
58#error long int is not a 32bit or 64bit byte
59#endif
60
61int
62_DEFUN (strncmp, (s1, s2, n),
63 _CONST char *s1 _AND
64 _CONST char *s2 _AND
65 size_t n)
66{
67#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
68 if (n == 0)
69 return 0;
70
71 while (n-- != 0 && *s1 == *s2)
72 {
73 if (n == 0 || *s1 == '\0')
74 break;
75 s1++;
76 s2++;
77 }
78
79 return (*(unsigned char *) s1) - (*(unsigned char *) s2);
80#else
81 unsigned long *a1;
82 unsigned long *a2;
83
84 if (n == 0)
85 return 0;
86
87 /* If s1 or s2 are unaligned, then compare bytes. */
88 if (!UNALIGNED (s1, s2))
89 {
90 /* If s1 and s2 are word-aligned, compare them a word at a time. */
91 a1 = (unsigned long*)s1;
92 a2 = (unsigned long*)s2;
93 while (n >= sizeof (long) && *a1 == *a2)
94 {
95 n -= sizeof (long);
96
97 /* If we've run out of bytes or hit a null, return zero
98 since we already know *a1 == *a2. */
99 if (n == 0 || DETECTNULL (*a1))
100 return 0;
101
102 a1++;
103 a2++;
104 }
105
106 /* A difference was detected in last few bytes of s1, so search bytewise */
107 s1 = (char*)a1;
108 s2 = (char*)a2;
109 }
110
111 while (n-- > 0 && *s1 == *s2)
112 {
113 /* If we've run out of bytes or hit a null, return zero
114 since we already know *s1 == *s2. */
115 if (n == 0 || *s1 == '\0')
116 return 0;
117 s1++;
118 s2++;
119 }
120 return (*(unsigned char *) s1) - (*(unsigned char *) s2);
121#endif /* not PREFER_SIZE_OVER_SPEED */
122}
diff --git a/firmware/libc/strrchr.c b/firmware/libc/strrchr.c
new file mode 100644
index 0000000000..31b0d049b3
--- /dev/null
+++ b/firmware/libc/strrchr.c
@@ -0,0 +1,59 @@
1/*
2FUNCTION
3 <<strrchr>>---reverse search for character in string
4
5INDEX
6 strrchr
7
8ANSI_SYNOPSIS
9 #include <string.h>
10 char * strrchr(const char *<[string]>, int <[c]>);
11
12TRAD_SYNOPSIS
13 #include <string.h>
14 char * strrchr(<[string]>, <[c]>);
15 char *<[string]>;
16 int *<[c]>;
17
18DESCRIPTION
19 This function finds the last occurence of <[c]> (converted to
20 a char) in the string pointed to by <[string]> (including the
21 terminating null character).
22
23RETURNS
24 Returns a pointer to the located character, or a null pointer
25 if <[c]> does not occur in <[string]>.
26
27PORTABILITY
28<<strrchr>> is ANSI C.
29
30<<strrchr>> requires no supporting OS subroutines.
31
32QUICKREF
33 strrchr ansi pure
34*/
35
36#include <string.h>
37
38char *
39_DEFUN (strrchr, (s, i),
40 _CONST char *s _AND
41 int i)
42{
43 _CONST char *last = NULL;
44
45 if (i)
46 {
47 while ((s=strchr(s, i)))
48 {
49 last = s;
50 s++;
51 }
52 }
53 else
54 {
55 last = strchr(s, i);
56 }
57
58 return (char *) last;
59}
diff --git a/firmware/libc/strstr.c b/firmware/libc/strstr.c
new file mode 100644
index 0000000000..73fab1cc63
--- /dev/null
+++ b/firmware/libc/strstr.c
@@ -0,0 +1,38 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 1991, 1992 Linus Torvalds
11 * (from linux/lib/string.c)
12 *
13 ****************************************************************************/
14
15#include <string.h>
16
17/**
18 * strstr - Find the first substring in a %NUL terminated string
19 * @s1: The string to be searched
20 * @s2: The string to search for
21 */
22char *strstr(const char *s1, const char *s2)
23{
24 int l1, l2;
25
26 l2 = strlen(s2);
27 if (!l2)
28 return (char *)s1;
29 l1 = strlen(s1);
30 while (l1 >= l2) {
31 l1--;
32 if (!memcmp(s1, s2, l2))
33 return (char *)s1;
34 s1++;
35 }
36 return NULL;
37}
38
diff --git a/firmware/libc/strtok.c b/firmware/libc/strtok.c
new file mode 100644
index 0000000000..9e2eddf599
--- /dev/null
+++ b/firmware/libc/strtok.c
@@ -0,0 +1,63 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Daniel Stenberg
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied. *
19 ****************************************************************************/
20
21#include "config.h"
22
23#ifndef HAVE_STRTOK_R
24#include <stddef.h>
25#include <string.h>
26
27char *
28strtok_r(char *ptr, const char *sep, char **end)
29{
30 if (!ptr)
31 /* we got NULL input so then we get our last position instead */
32 ptr = *end;
33
34 /* pass all letters that are including in the separator string */
35 while (*ptr && strchr(sep, *ptr))
36 ++ptr;
37
38 if (*ptr) {
39 /* so this is where the next piece of string starts */
40 char *start = ptr;
41
42 /* set the end pointer to the first byte after the start */
43 *end = start + 1;
44
45 /* scan through the string to find where it ends, it ends on a
46 null byte or a character that exists in the separator string */
47 while (**end && !strchr(sep, **end))
48 ++*end;
49
50 if (**end) {
51 /* the end is not a null byte */
52 **end = '\0'; /* zero terminate it! */
53 ++*end; /* advance last pointer to beyond the null byte */
54 }
55
56 return start; /* return the position where the string starts */
57 }
58
59 /* we ended up on a null byte, there are no more strings to find! */
60 return NULL;
61}
62
63#endif /* this was only compiled if strtok_r wasn't present */