summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-05-30 21:03:17 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-05-30 21:03:17 +0000
commitb69338f9f8ae2ae957949a0f4af9749ebb4adc3f (patch)
treec29019589ce21007d1ff99dd74d3115f19dbd3f4
parent80361f88818ad1ce2ebc00a10f7aa8de1605b3a5 (diff)
downloadrockbox-b69338f9f8ae2ae957949a0f4af9749ebb4adc3f.tar.gz
rockbox-b69338f9f8ae2ae957949a0f4af9749ebb4adc3f.zip
Added code from libc instead of requiring newlib
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@835 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/common/errno.c1
-rw-r--r--firmware/common/errno.h134
-rw-r--r--firmware/common/memcpy.c111
-rw-r--r--firmware/common/memset.c109
-rw-r--r--firmware/common/qsort.c222
-rw-r--r--firmware/common/strchr.c108
-rw-r--r--firmware/common/strcmp.c106
-rw-r--r--firmware/common/strcpy.c99
-rw-r--r--firmware/common/strlen.c88
-rw-r--r--firmware/common/strncmp.c122
-rw-r--r--firmware/common/strncpy.c125
-rw-r--r--firmware/common/strrchr.c59
12 files changed, 1284 insertions, 0 deletions
diff --git a/firmware/common/errno.c b/firmware/common/errno.c
new file mode 100644
index 0000000000..6e7bb62b51
--- /dev/null
+++ b/firmware/common/errno.c
@@ -0,0 +1 @@
int errno;
diff --git a/firmware/common/errno.h b/firmware/common/errno.h
new file mode 100644
index 0000000000..4162f6a9ed
--- /dev/null
+++ b/firmware/common/errno.h
@@ -0,0 +1,134 @@
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#ifndef _SYS_ERRNO_H_
6
7extern int errno;
8
9#define EPERM 1 /* Not super-user */
10#define ENOENT 2 /* No such file or directory */
11#define ESRCH 3 /* No such process */
12#define EINTR 4 /* Interrupted system call */
13#define EIO 5 /* I/O error */
14#define ENXIO 6 /* No such device or address */
15#define E2BIG 7 /* Arg list too long */
16#define ENOEXEC 8 /* Exec format error */
17#define EBADF 9 /* Bad file number */
18#define ECHILD 10 /* No children */
19#define EAGAIN 11 /* No more processes */
20#define ENOMEM 12 /* Not enough core */
21#define EACCES 13 /* Permission denied */
22#define EFAULT 14 /* Bad address */
23#define ENOTBLK 15 /* Block device required */
24#define EBUSY 16 /* Mount device busy */
25#define EEXIST 17 /* File exists */
26#define EXDEV 18 /* Cross-device link */
27#define ENODEV 19 /* No such device */
28#define ENOTDIR 20 /* Not a directory */
29#define EISDIR 21 /* Is a directory */
30#define EINVAL 22 /* Invalid argument */
31#define ENFILE 23 /* Too many open files in system */
32#define EMFILE 24 /* Too many open files */
33#define ENOTTY 25 /* Not a typewriter */
34#define ETXTBSY 26 /* Text file busy */
35#define EFBIG 27 /* File too large */
36#define ENOSPC 28 /* No space left on device */
37#define ESPIPE 29 /* Illegal seek */
38#define EROFS 30 /* Read only file system */
39#define EMLINK 31 /* Too many links */
40#define EPIPE 32 /* Broken pipe */
41#define EDOM 33 /* Math arg out of domain of func */
42#define ERANGE 34 /* Math result not representable */
43#define ENOMSG 35 /* No message of desired type */
44#define EIDRM 36 /* Identifier removed */
45#define ECHRNG 37 /* Channel number out of range */
46#define EL2NSYNC 38 /* Level 2 not synchronized */
47#define EL3HLT 39 /* Level 3 halted */
48#define EL3RST 40 /* Level 3 reset */
49#define ELNRNG 41 /* Link number out of range */
50#define EUNATCH 42 /* Protocol driver not attached */
51#define ENOCSI 43 /* No CSI structure available */
52#define EL2HLT 44 /* Level 2 halted */
53#define EDEADLK 45 /* Deadlock condition */
54#define ENOLCK 46 /* No record locks available */
55#define EBADE 50 /* Invalid exchange */
56#define EBADR 51 /* Invalid request descriptor */
57#define EXFULL 52 /* Exchange full */
58#define ENOANO 53 /* No anode */
59#define EBADRQC 54 /* Invalid request code */
60#define EBADSLT 55 /* Invalid slot */
61#define EDEADLOCK 56 /* File locking deadlock error */
62#define EBFONT 57 /* Bad font file fmt */
63#define ENOSTR 60 /* Device not a stream */
64#define ENODATA 61 /* No data (for no delay io) */
65#define ETIME 62 /* Timer expired */
66#define ENOSR 63 /* Out of streams resources */
67#define ENONET 64 /* Machine is not on the network */
68#define ENOPKG 65 /* Package not installed */
69#define EREMOTE 66 /* The object is remote */
70#define ENOLINK 67 /* The link has been severed */
71#define EADV 68 /* Advertise error */
72#define ESRMNT 69 /* Srmount error */
73#define ECOMM 70 /* Communication error on send */
74#define EPROTO 71 /* Protocol error */
75#define EMULTIHOP 74 /* Multihop attempted */
76#define ELBIN 75 /* Inode is remote (not really error) */
77#define EDOTDOT 76 /* Cross mount point (not really error) */
78#define EBADMSG 77 /* Trying to read unreadable message */
79#define ENOTUNIQ 80 /* Given log. name not unique */
80#define EBADFD 81 /* f.d. invalid for this operation */
81#define EREMCHG 82 /* Remote address changed */
82#define ELIBACC 83 /* Can't access a needed shared lib */
83#define ELIBBAD 84 /* Accessing a corrupted shared lib */
84#define ELIBSCN 85 /* .lib section in a.out corrupted */
85#define ELIBMAX 86 /* Attempting to link in too many libs */
86#define ELIBEXEC 87 /* Attempting to exec a shared library */
87#define ENOSYS 88 /* Function not implemented */
88#define ENMFILE 89 /* No more files */
89#define ENOTEMPTY 90 /* Directory not empty */
90#define ENAMETOOLONG 91 /* File or path name too long */
91#define ELOOP 92 /* Too many symbolic links */
92#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
93#define EPFNOSUPPORT 96 /* Protocol family not supported */
94#define ECONNRESET 104 /* Connection reset by peer */
95#define ENOBUFS 105 /* No buffer space available */
96#define EAFNOSUPPORT 106 /* Address family not supported by protocol family */
97#define EPROTOTYPE 107 /* Protocol wrong type for socket */
98#define ENOTSOCK 108 /* Socket operation on non-socket */
99#define ENOPROTOOPT 109 /* Protocol not available */
100#define ESHUTDOWN 110 /* Can't send after socket shutdown */
101#define ECONNREFUSED 111 /* Connection refused */
102#define EADDRINUSE 112 /* Address already in use */
103#define ECONNABORTED 113 /* Connection aborted */
104#define ENETUNREACH 114 /* Network is unreachable */
105#define ENETDOWN 115 /* Network interface is not configured */
106#define ETIMEDOUT 116 /* Connection timed out */
107#define EHOSTDOWN 117 /* Host is down */
108#define EHOSTUNREACH 118 /* Host is unreachable */
109#define EINPROGRESS 119 /* Connection already in progress */
110#define EALREADY 120 /* Socket already connected */
111#define EDESTADDRREQ 121 /* Destination address required */
112#define EMSGSIZE 122 /* Message too long */
113#define EPROTONOSUPPORT 123 /* Unknown protocol */
114#define ESOCKTNOSUPPORT 124 /* Socket type not supported */
115#define EADDRNOTAVAIL 125 /* Address not available */
116#define ENETRESET 126
117#define EISCONN 127 /* Socket is already connected */
118#define ENOTCONN 128 /* Socket is not connected */
119#define ETOOMANYREFS 129
120#define EPROCLIM 130
121#define EUSERS 131
122#define EDQUOT 132
123#define ESTALE 133
124#define ENOTSUP 134 /* Not supported */
125#define ENOMEDIUM 135 /* No medium (in tape drive) */
126#define ENOSHARE 136 /* No such host or network path */
127#define ECASECLASH 137 /* Filename exists with different case */
128
129/* From cygwin32. */
130#define EWOULDBLOCK EAGAIN /* Operation would block */
131
132#define __ELASTERROR 2000 /* Users can add values starting here */
133
134#endif /* _SYS_ERRNO_H */
diff --git a/firmware/common/memcpy.c b/firmware/common/memcpy.c
new file mode 100644
index 0000000000..5336f25a91
--- /dev/null
+++ b/firmware/common/memcpy.c
@@ -0,0 +1,111 @@
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 <_ansi.h>
36#include <stddef.h>
37#include <limits.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/* Threshhold 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)
57{
58#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
59 char *dst = (char *) dst0;
60 char *src = (char *) src0;
61
62 _PTR save = dst0;
63
64 while (len0--)
65 {
66 *dst++ = *src++;
67 }
68
69 return save;
70#else
71 char *dst = dst0;
72 _CONST char *src = src0;
73 long *aligned_dst;
74 _CONST long *aligned_src;
75 int len = len0;
76
77 /* If the size is small, or either SRC or DST is unaligned,
78 then punt into the byte copy loop. This should be rare. */
79 if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
80 {
81 aligned_dst = (long*)dst;
82 aligned_src = (long*)src;
83
84 /* Copy 4X long words at a time if possible. */
85 while (len >= BIGBLOCKSIZE)
86 {
87 *aligned_dst++ = *aligned_src++;
88 *aligned_dst++ = *aligned_src++;
89 *aligned_dst++ = *aligned_src++;
90 *aligned_dst++ = *aligned_src++;
91 len -= BIGBLOCKSIZE;
92 }
93
94 /* Copy one long word at a time if possible. */
95 while (len >= LITTLEBLOCKSIZE)
96 {
97 *aligned_dst++ = *aligned_src++;
98 len -= LITTLEBLOCKSIZE;
99 }
100
101 /* Pick up any residual with a byte copier. */
102 dst = (char*)aligned_dst;
103 src = (char*)aligned_src;
104 }
105
106 while (len--)
107 *dst++ = *src++;
108
109 return dst0;
110#endif /* not PREFER_SIZE_OVER_SPEED */
111}
diff --git a/firmware/common/memset.c b/firmware/common/memset.c
new file mode 100644
index 0000000000..a5890c8847
--- /dev/null
+++ b/firmware/common/memset.c
@@ -0,0 +1,109 @@
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
38#define LBLOCKSIZE (sizeof(long))
39#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
40#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
41
42_PTR
43_DEFUN (memset, (m, c, n),
44 _PTR m _AND
45 int c _AND
46 size_t n)
47{
48#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
49 char *s = (char *) m;
50
51 while (n-- != 0)
52 {
53 *s++ = (char) c;
54 }
55
56 return m;
57#else
58 char *s = (char *) m;
59 int i;
60 unsigned long buffer;
61 unsigned long *aligned_addr;
62
63 if (!TOO_SMALL (n) && !UNALIGNED (m))
64 {
65 /* If we get this far, we know that n is large and m is word-aligned. */
66
67 aligned_addr = (unsigned long*)m;
68
69 /* Store C into each char sized location in BUFFER so that
70 we can set large blocks quickly. */
71 c &= 0xff;
72 if (LBLOCKSIZE == 4)
73 {
74 buffer = (c << 8) | c;
75 buffer |= (buffer << 16);
76 }
77 else
78 {
79 buffer = 0;
80 for (i = 0; i < LBLOCKSIZE; i++)
81 buffer = (buffer << 8) | c;
82 }
83
84 while (n >= LBLOCKSIZE*4)
85 {
86 *aligned_addr++ = buffer;
87 *aligned_addr++ = buffer;
88 *aligned_addr++ = buffer;
89 *aligned_addr++ = buffer;
90 n -= 4*LBLOCKSIZE;
91 }
92
93 while (n >= LBLOCKSIZE)
94 {
95 *aligned_addr++ = buffer;
96 n -= LBLOCKSIZE;
97 }
98 /* Pick up the remainder with a bytewise loop. */
99 s = (char*)aligned_addr;
100 }
101
102 while (n--)
103 {
104 *s++ = (char)c;
105 }
106
107 return m;
108#endif /* not PREFER_SIZE_OVER_SPEED */
109}
diff --git a/firmware/common/qsort.c b/firmware/common/qsort.c
new file mode 100644
index 0000000000..d47f470999
--- /dev/null
+++ b/firmware/common/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 (*)()));
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)())
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)())
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(pd - pc, pn - pd - es);
212 vecswap(pb, pn - r, r);
213 if ((r = pb - pa) > es)
214 qsort(a, r / es, es, cmp);
215 if ((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/common/strchr.c b/firmware/common/strchr.c
new file mode 100644
index 0000000000..de4585f758
--- /dev/null
+++ b/firmware/common/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/common/strcmp.c b/firmware/common/strcmp.c
new file mode 100644
index 0000000000..81d65272ec
--- /dev/null
+++ b/firmware/common/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/common/strcpy.c b/firmware/common/strcpy.c
new file mode 100644
index 0000000000..3dc3c33f60
--- /dev/null
+++ b/firmware/common/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/common/strlen.c b/firmware/common/strlen.c
new file mode 100644
index 0000000000..4249e14c78
--- /dev/null
+++ b/firmware/common/strlen.c
@@ -0,0 +1,88 @@
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 <_ansi.h>
35#include <string.h>
36#include <limits.h>
37
38#define LBLOCKSIZE (sizeof (long))
39#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
40
41#if LONG_MAX == 2147483647L
42#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
43#else
44#if LONG_MAX == 9223372036854775807L
45/* Nonzero if X (a long int) contains a NULL byte. */
46#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
47#else
48#error long int is not a 32bit or 64bit type.
49#endif
50#endif
51
52#ifndef DETECTNULL
53#error long int is not a 32bit or 64bit byte
54#endif
55
56size_t
57_DEFUN (strlen, (str),
58 _CONST char *str)
59{
60#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
61 _CONST char *start = str;
62
63 while (*str)
64 str++;
65
66 return str - start;
67#else
68 _CONST char *start = str;
69 unsigned long *aligned_addr;
70
71 if (!UNALIGNED (str))
72 {
73 /* If the string is word-aligned, we can check for the presence of
74 a null in each word-sized block. */
75 aligned_addr = (unsigned long*)str;
76 while (!DETECTNULL (*aligned_addr))
77 aligned_addr++;
78
79 /* Once a null is detected, we check each byte in that block for a
80 precise position of the null. */
81 str = (char*)aligned_addr;
82 }
83
84 while (*str)
85 str++;
86 return str - start;
87#endif /* not PREFER_SIZE_OVER_SPEED */
88}
diff --git a/firmware/common/strncmp.c b/firmware/common/strncmp.c
new file mode 100644
index 0000000000..9801b7d924
--- /dev/null
+++ b/firmware/common/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/common/strncpy.c b/firmware/common/strncpy.c
new file mode 100644
index 0000000000..7c1973ba66
--- /dev/null
+++ b/firmware/common/strncpy.c
@@ -0,0 +1,125 @@
1/*
2FUNCTION
3 <<strncpy>>---counted copy string
4
5INDEX
6 strncpy
7
8ANSI_SYNOPSIS
9 #include <string.h>
10 char *strncpy(char *<[dst]>, const char *<[src]>, size_t <[length]>);
11
12TRAD_SYNOPSIS
13 #include <string.h>
14 char *strncpy(<[dst]>, <[src]>, <[length]>)
15 char *<[dst]>;
16 char *<[src]>;
17 size_t <[length]>;
18
19DESCRIPTION
20 <<strncpy>> copies not more than <[length]> characters from the
21 the string pointed to by <[src]> (including the terminating
22 null character) to the array pointed to by <[dst]>. If the
23 string pointed to by <[src]> is shorter than <[length]>
24 characters, null characters are appended to the destination
25 array until a total of <[length]> characters have been
26 written.
27
28RETURNS
29 This function returns the initial value of <[dst]>.
30
31PORTABILITY
32<<strncpy>> is ANSI C.
33
34<<strncpy>> requires no supporting OS subroutines.
35
36QUICKREF
37 strncpy ansi pure
38*/
39
40#include <string.h>
41#include <limits.h>
42
43/*SUPPRESS 560*/
44/*SUPPRESS 530*/
45
46/* Nonzero if either X or Y is not aligned on a "long" boundary. */
47#define UNALIGNED(X, Y) \
48 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
49
50#if LONG_MAX == 2147483647L
51#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
52#else
53#if LONG_MAX == 9223372036854775807L
54/* Nonzero if X (a long int) contains a NULL byte. */
55#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
56#else
57#error long int is not a 32bit or 64bit type.
58#endif
59#endif
60
61#ifndef DETECTNULL
62#error long int is not a 32bit or 64bit byte
63#endif
64
65#define TOO_SMALL(LEN) ((LEN) < sizeof (long))
66
67char *
68_DEFUN (strncpy, (dst0, src0),
69 char *dst0 _AND
70 _CONST char *src0 _AND
71 size_t count)
72{
73#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
74 char *dscan;
75 _CONST char *sscan;
76
77 dscan = dst0;
78 sscan = src0;
79 while (count > 0)
80 {
81 --count;
82 if ((*dscan++ = *sscan++) == '\0')
83 break;
84 }
85 while (count-- > 0)
86 *dscan++ = '\0';
87
88 return dst0;
89#else
90 char *dst = dst0;
91 _CONST char *src = src0;
92 long *aligned_dst;
93 _CONST long *aligned_src;
94
95 /* If SRC and DEST is aligned and count large enough, then copy words. */
96 if (!UNALIGNED (src, dst) && !TOO_SMALL (count))
97 {
98 aligned_dst = (long*)dst;
99 aligned_src = (long*)src;
100
101 /* SRC and DEST are both "long int" aligned, try to do "long int"
102 sized copies. */
103 while (count >= sizeof (long int) && !DETECTNULL(*aligned_src))
104 {
105 count -= sizeof (long int);
106 *aligned_dst++ = *aligned_src++;
107 }
108
109 dst = (char*)aligned_dst;
110 src = (char*)aligned_src;
111 }
112
113 while (count > 0)
114 {
115 --count;
116 if ((*dst++ = *src++) == '\0')
117 break;
118 }
119
120 while (count-- > 0)
121 *dst++ = '\0';
122
123 return dst0;
124#endif /* not PREFER_SIZE_OVER_SPEED */
125}
diff --git a/firmware/common/strrchr.c b/firmware/common/strrchr.c
new file mode 100644
index 0000000000..4f903afe2b
--- /dev/null
+++ b/firmware/common/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}