Added code from libc instead of requiring newlib

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@835 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Björn Stenberg 2002-05-30 21:03:17 +00:00
parent 80361f8881
commit b69338f9f8
12 changed files with 1284 additions and 0 deletions

1
firmware/common/errno.c Normal file
View file

@ -0,0 +1 @@
int errno;

134
firmware/common/errno.h Normal file
View file

@ -0,0 +1,134 @@
/* errno is not a global variable, because that would make using it
non-reentrant. Instead, its address is returned by the function
__errno. */
#ifndef _SYS_ERRNO_H_
extern int errno;
#define EPERM 1 /* Not super-user */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No children */
#define EAGAIN 11 /* No more processes */
#define ENOMEM 12 /* Not enough core */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Mount device busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* Too many open files in system */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math arg out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define ENOMSG 35 /* No message of desired type */
#define EIDRM 36 /* Identifier removed */
#define ECHRNG 37 /* Channel number out of range */
#define EL2NSYNC 38 /* Level 2 not synchronized */
#define EL3HLT 39 /* Level 3 halted */
#define EL3RST 40 /* Level 3 reset */
#define ELNRNG 41 /* Link number out of range */
#define EUNATCH 42 /* Protocol driver not attached */
#define ENOCSI 43 /* No CSI structure available */
#define EL2HLT 44 /* Level 2 halted */
#define EDEADLK 45 /* Deadlock condition */
#define ENOLCK 46 /* No record locks available */
#define EBADE 50 /* Invalid exchange */
#define EBADR 51 /* Invalid request descriptor */
#define EXFULL 52 /* Exchange full */
#define ENOANO 53 /* No anode */
#define EBADRQC 54 /* Invalid request code */
#define EBADSLT 55 /* Invalid slot */
#define EDEADLOCK 56 /* File locking deadlock error */
#define EBFONT 57 /* Bad font file fmt */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data (for no delay io) */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* The object is remote */
#define ENOLINK 67 /* The link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 74 /* Multihop attempted */
#define ELBIN 75 /* Inode is remote (not really error) */
#define EDOTDOT 76 /* Cross mount point (not really error) */
#define EBADMSG 77 /* Trying to read unreadable message */
#define ENOTUNIQ 80 /* Given log. name not unique */
#define EBADFD 81 /* f.d. invalid for this operation */
#define EREMCHG 82 /* Remote address changed */
#define ELIBACC 83 /* Can't access a needed shared lib */
#define ELIBBAD 84 /* Accessing a corrupted shared lib */
#define ELIBSCN 85 /* .lib section in a.out corrupted */
#define ELIBMAX 86 /* Attempting to link in too many libs */
#define ELIBEXEC 87 /* Attempting to exec a shared library */
#define ENOSYS 88 /* Function not implemented */
#define ENMFILE 89 /* No more files */
#define ENOTEMPTY 90 /* Directory not empty */
#define ENAMETOOLONG 91 /* File or path name too long */
#define ELOOP 92 /* Too many symbolic links */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EAFNOSUPPORT 106 /* Address family not supported by protocol family */
#define EPROTOTYPE 107 /* Protocol wrong type for socket */
#define ENOTSOCK 108 /* Socket operation on non-socket */
#define ENOPROTOOPT 109 /* Protocol not available */
#define ESHUTDOWN 110 /* Can't send after socket shutdown */
#define ECONNREFUSED 111 /* Connection refused */
#define EADDRINUSE 112 /* Address already in use */
#define ECONNABORTED 113 /* Connection aborted */
#define ENETUNREACH 114 /* Network is unreachable */
#define ENETDOWN 115 /* Network interface is not configured */
#define ETIMEDOUT 116 /* Connection timed out */
#define EHOSTDOWN 117 /* Host is down */
#define EHOSTUNREACH 118 /* Host is unreachable */
#define EINPROGRESS 119 /* Connection already in progress */
#define EALREADY 120 /* Socket already connected */
#define EDESTADDRREQ 121 /* Destination address required */
#define EMSGSIZE 122 /* Message too long */
#define EPROTONOSUPPORT 123 /* Unknown protocol */
#define ESOCKTNOSUPPORT 124 /* Socket type not supported */
#define EADDRNOTAVAIL 125 /* Address not available */
#define ENETRESET 126
#define EISCONN 127 /* Socket is already connected */
#define ENOTCONN 128 /* Socket is not connected */
#define ETOOMANYREFS 129
#define EPROCLIM 130
#define EUSERS 131
#define EDQUOT 132
#define ESTALE 133
#define ENOTSUP 134 /* Not supported */
#define ENOMEDIUM 135 /* No medium (in tape drive) */
#define ENOSHARE 136 /* No such host or network path */
#define ECASECLASH 137 /* Filename exists with different case */
/* From cygwin32. */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define __ELASTERROR 2000 /* Users can add values starting here */
#endif /* _SYS_ERRNO_H */

111
firmware/common/memcpy.c Normal file
View file

@ -0,0 +1,111 @@
/*
FUNCTION
<<memcpy>>---copy memory regions
ANSI_SYNOPSIS
#include <string.h>
void* memcpy(void *<[out]>, const void *<[in]>, size_t <[n]>);
TRAD_SYNOPSIS
void *memcpy(<[out]>, <[in]>, <[n]>
void *<[out]>;
void *<[in]>;
size_t <[n]>;
DESCRIPTION
This function copies <[n]> bytes from the memory region
pointed to by <[in]> to the memory region pointed to by
<[out]>.
If the regions overlap, the behavior is undefined.
RETURNS
<<memcpy>> returns a pointer to the first byte of the <[out]>
region.
PORTABILITY
<<memcpy>> is ANSI C.
<<memcpy>> requires no supporting OS subroutines.
QUICKREF
memcpy ansi pure
*/
#include <_ansi.h>
#include <stddef.h>
#include <limits.h>
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
/* How many bytes are copied each iteration of the 4X unrolled loop. */
#define BIGBLOCKSIZE (sizeof (long) << 2)
/* How many bytes are copied each iteration of the word copy loop. */
#define LITTLEBLOCKSIZE (sizeof (long))
/* Threshhold for punting to the byte copier. */
#define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
_PTR
_DEFUN (memcpy, (dst0, src0, len0),
_PTR dst0 _AND
_CONST _PTR src0 _AND
size_t len0)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *dst = (char *) dst0;
char *src = (char *) src0;
_PTR save = dst0;
while (len0--)
{
*dst++ = *src++;
}
return save;
#else
char *dst = dst0;
_CONST char *src = src0;
long *aligned_dst;
_CONST long *aligned_src;
int len = len0;
/* If the size is small, or either SRC or DST is unaligned,
then punt into the byte copy loop. This should be rare. */
if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
{
aligned_dst = (long*)dst;
aligned_src = (long*)src;
/* Copy 4X long words at a time if possible. */
while (len >= BIGBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
len -= BIGBLOCKSIZE;
}
/* Copy one long word at a time if possible. */
while (len >= LITTLEBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
len -= LITTLEBLOCKSIZE;
}
/* Pick up any residual with a byte copier. */
dst = (char*)aligned_dst;
src = (char*)aligned_src;
}
while (len--)
*dst++ = *src++;
return dst0;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

109
firmware/common/memset.c Normal file
View file

@ -0,0 +1,109 @@
/*
FUNCTION
<<memset>>---set an area of memory
INDEX
memset
ANSI_SYNOPSIS
#include <string.h>
void *memset(const void *<[dst]>, int <[c]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.h>
void *memset(<[dst]>, <[c]>, <[length]>)
void *<[dst]>;
int <[c]>;
size_t <[length]>;
DESCRIPTION
This function converts the argument <[c]> into an unsigned
char and fills the first <[length]> characters of the array
pointed to by <[dst]> to the value.
RETURNS
<<memset>> returns the value of <[m]>.
PORTABILITY
<<memset>> is ANSI C.
<<memset>> requires no supporting OS subroutines.
QUICKREF
memset ansi pure
*/
#include <string.h>
#define LBLOCKSIZE (sizeof(long))
#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
_PTR
_DEFUN (memset, (m, c, n),
_PTR m _AND
int c _AND
size_t n)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *s = (char *) m;
while (n-- != 0)
{
*s++ = (char) c;
}
return m;
#else
char *s = (char *) m;
int i;
unsigned long buffer;
unsigned long *aligned_addr;
if (!TOO_SMALL (n) && !UNALIGNED (m))
{
/* If we get this far, we know that n is large and m is word-aligned. */
aligned_addr = (unsigned long*)m;
/* Store C into each char sized location in BUFFER so that
we can set large blocks quickly. */
c &= 0xff;
if (LBLOCKSIZE == 4)
{
buffer = (c << 8) | c;
buffer |= (buffer << 16);
}
else
{
buffer = 0;
for (i = 0; i < LBLOCKSIZE; i++)
buffer = (buffer << 8) | c;
}
while (n >= LBLOCKSIZE*4)
{
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
n -= 4*LBLOCKSIZE;
}
while (n >= LBLOCKSIZE)
{
*aligned_addr++ = buffer;
n -= LBLOCKSIZE;
}
/* Pick up the remainder with a bytewise loop. */
s = (char*)aligned_addr;
}
while (n--)
{
*s++ = (char)c;
}
return m;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

222
firmware/common/qsort.c Normal file
View file

@ -0,0 +1,222 @@
/*
FUNCTION
<<qsort>>---sort an array
INDEX
qsort
ANSI_SYNOPSIS
#include <stdlib.h>
void qsort(void *<[base]>, size_t <[nmemb]>, size_t <[size]>,
int (*<[compar]>)(const void *, const void *) );
TRAD_SYNOPSIS
#include <stdlib.h>
qsort(<[base]>, <[nmemb]>, <[size]>, <[compar]> )
char *<[base]>;
size_t <[nmemb]>;
size_t <[size]>;
int (*<[compar]>)();
DESCRIPTION
<<qsort>> sorts an array (beginning at <[base]>) of <[nmemb]> objects.
<[size]> describes the size of each element of the array.
You must supply a pointer to a comparison function, using the argument
shown as <[compar]>. (This permits sorting objects of unknown
properties.) Define the comparison function to accept two arguments,
each a pointer to an element of the array starting at <[base]>. The
result of <<(*<[compar]>)>> must be negative if the first argument is
less than the second, zero if the two arguments match, and positive if
the first argument is greater than the second (where ``less than'' and
``greater than'' refer to whatever arbitrary ordering is appropriate).
The array is sorted in place; that is, when <<qsort>> returns, the
array elements beginning at <[base]> have been reordered.
RETURNS
<<qsort>> does not return a result.
PORTABILITY
<<qsort>> is required by ANSI (without specifying the sorting algorithm).
*/
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <_ansi.h>
#include <stdlib.h>
#ifndef __GNUC__
#define inline
#endif
static inline char *med3 _PARAMS((char *, char *, char *, int (*)()));
static inline void swapfunc _PARAMS((char *, char *, int, int));
#define min(a, b) (a) < (b) ? a : b
/*
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
*/
#define swapcode(TYPE, parmi, parmj, n) { \
long i = (n) / sizeof (TYPE); \
register TYPE *pi = (TYPE *) (parmi); \
register TYPE *pj = (TYPE *) (parmj); \
do { \
register TYPE t = *pi; \
*pi++ = *pj; \
*pj++ = t; \
} while (--i > 0); \
}
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
static inline void
_DEFUN(swapfunc, (a, b, n, swaptype),
char *a _AND
char *b _AND
int n _AND
int swaptype)
{
if(swaptype <= 1)
swapcode(long, a, b, n)
else
swapcode(char, a, b, n)
}
#define swap(a, b) \
if (swaptype == 0) { \
long t = *(long *)(a); \
*(long *)(a) = *(long *)(b); \
*(long *)(b) = t; \
} else \
swapfunc(a, b, es, swaptype)
#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
static inline char *
_DEFUN(med3, (a, b, c, cmp),
char *a _AND
char *b _AND
char *c _AND
int (*cmp)())
{
return cmp(a, b) < 0 ?
(cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
:(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
}
void
_DEFUN(qsort, (a, n, es, cmp),
void *a _AND
size_t n _AND
size_t es _AND
int (*cmp)())
{
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
int d, r, swaptype, swap_cnt;
loop: SWAPINIT(a, es);
swap_cnt = 0;
if (n < 7) {
for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
pl -= es)
swap(pl, pl - es);
return;
}
pm = (char *) a + (n / 2) * es;
if (n > 7) {
pl = a;
pn = (char *) a + (n - 1) * es;
if (n > 40) {
d = (n / 8) * es;
pl = med3(pl, pl + d, pl + 2 * d, cmp);
pm = med3(pm - d, pm, pm + d, cmp);
pn = med3(pn - 2 * d, pn - d, pn, cmp);
}
pm = med3(pl, pm, pn, cmp);
}
swap(a, pm);
pa = pb = (char *) a + es;
pc = pd = (char *) a + (n - 1) * es;
for (;;) {
while (pb <= pc && (r = cmp(pb, a)) <= 0) {
if (r == 0) {
swap_cnt = 1;
swap(pa, pb);
pa += es;
}
pb += es;
}
while (pb <= pc && (r = cmp(pc, a)) >= 0) {
if (r == 0) {
swap_cnt = 1;
swap(pc, pd);
pd -= es;
}
pc -= es;
}
if (pb > pc)
break;
swap(pb, pc);
swap_cnt = 1;
pb += es;
pc -= es;
}
if (swap_cnt == 0) { /* Switch to insertion sort */
for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
pl -= es)
swap(pl, pl - es);
return;
}
pn = (char *) a + n * es;
r = min(pa - (char *)a, pb - pa);
vecswap(a, pb - r, r);
r = min(pd - pc, pn - pd - es);
vecswap(pb, pn - r, r);
if ((r = pb - pa) > es)
qsort(a, r / es, es, cmp);
if ((r = pd - pc) > es) {
/* Iterate rather than recurse to save stack space */
a = pn - r;
n = r / es;
goto loop;
}
/* qsort(pn - r, r / es, es, cmp);*/
}

108
firmware/common/strchr.c Normal file
View file

@ -0,0 +1,108 @@
/*
FUNCTION
<<strchr>>---search for character in string
INDEX
strchr
ANSI_SYNOPSIS
#include <string.h>
char * strchr(const char *<[string]>, int <[c]>);
TRAD_SYNOPSIS
#include <string.h>
char * strchr(<[string]>, <[c]>);
char *<[string]>;
int *<[c]>;
DESCRIPTION
This function finds the first occurence of <[c]> (converted to
a char) in the string pointed to by <[string]> (including the
terminating null character).
RETURNS
Returns a pointer to the located character, or a null pointer
if <[c]> does not occur in <[string]>.
PORTABILITY
<<strchr>> is ANSI C.
<<strchr>> requires no supporting OS subroutines.
QUICKREF
strchr ansi pure
*/
#include <string.h>
#include <limits.h>
/* Nonzero if X is not aligned on a "long" boundary. */
#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
/* How many bytes are loaded each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof (long))
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
/* DETECTCHAR returns nonzero if (long)X contains the byte used
to fill (long)MASK. */
#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK))
char *
_DEFUN (strchr, (s1, i),
_CONST char *s1 _AND
int i)
{
_CONST unsigned char *s = (_CONST unsigned char *)s1;
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
unsigned char c = (unsigned int)i;
while (*s && *s != c)
{
s++;
}
if (*s != c)
{
s = NULL;
}
return (char *) s;
#else
unsigned char c = (unsigned char)i;
unsigned long mask,j;
unsigned long *aligned_addr;
if (!UNALIGNED (s))
{
mask = 0;
for (j = 0; j < LBLOCKSIZE; j++)
mask = (mask << 8) | c;
aligned_addr = (unsigned long*)s;
while (!DETECTNULL (*aligned_addr) && !DETECTCHAR (*aligned_addr, mask))
aligned_addr++;
/* The block of bytes currently pointed to by aligned_addr
contains either a null or the target char, or both. We
catch it using the bytewise search. */
s = (unsigned char*)aligned_addr;
}
while (*s && *s != c)
s++;
if (*s == c)
return (char *)s;
return NULL;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

106
firmware/common/strcmp.c Normal file
View file

@ -0,0 +1,106 @@
/*
FUNCTION
<<strcmp>>---character string compare
INDEX
strcmp
ANSI_SYNOPSIS
#include <string.h>
int strcmp(const char *<[a]>, const char *<[b]>);
TRAD_SYNOPSIS
#include <string.h>
int strcmp(<[a]>, <[b]>)
char *<[a]>;
char *<[b]>;
DESCRIPTION
<<strcmp>> compares the string at <[a]> to
the string at <[b]>.
RETURNS
If <<*<[a]>>> sorts lexicographically after <<*<[b]>>>,
<<strcmp>> returns a number greater than zero. If the two
strings match, <<strcmp>> returns zero. If <<*<[a]>>>
sorts lexicographically before <<*<[b]>>>, <<strcmp>> returns a
number less than zero.
PORTABILITY
<<strcmp>> is ANSI C.
<<strcmp>> requires no supporting OS subroutines.
QUICKREF
strcmp ansi pure
*/
#include <string.h>
#include <limits.h>
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
/* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
int
_DEFUN (strcmp, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
while (*s1 != '\0' && *s1 == *s2)
{
s1++;
s2++;
}
return (*(unsigned char *) s1) - (*(unsigned char *) s2);
#else
unsigned long *a1;
unsigned long *a2;
/* If s1 or s2 are unaligned, then compare bytes. */
if (!UNALIGNED (s1, s2))
{
/* If s1 and s2 are word-aligned, compare them a word at a time. */
a1 = (unsigned long*)s1;
a2 = (unsigned long*)s2;
while (*a1 == *a2)
{
/* To get here, *a1 == *a2, thus if we find a null in *a1,
then the strings must be equal, so return zero. */
if (DETECTNULL (*a1))
return 0;
a1++;
a2++;
}
/* A difference was detected in last few bytes of s1, so search bytewise */
s1 = (char*)a1;
s2 = (char*)a2;
}
while (*s1 != '\0' && *s1 == *s2)
{
s1++;
s2++;
}
return (*(unsigned char *) s1) - (*(unsigned char *) s2);
#endif /* not PREFER_SIZE_OVER_SPEED */
}

99
firmware/common/strcpy.c Normal file
View file

@ -0,0 +1,99 @@
/*
FUNCTION
<<strcpy>>---copy string
INDEX
strcpy
ANSI_SYNOPSIS
#include <string.h>
char *strcpy(char *<[dst]>, const char *<[src]>);
TRAD_SYNOPSIS
#include <string.h>
char *strcpy(<[dst]>, <[src]>)
char *<[dst]>;
char *<[src]>;
DESCRIPTION
<<strcpy>> copies the string pointed to by <[src]>
(including the terminating null character) to the array
pointed to by <[dst]>.
RETURNS
This function returns the initial value of <[dst]>.
PORTABILITY
<<strcpy>> is ANSI C.
<<strcpy>> requires no supporting OS subroutines.
QUICKREF
strcpy ansi pure
*/
#include <string.h>
#include <limits.h>
/*SUPPRESS 560*/
/*SUPPRESS 530*/
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
char*
_DEFUN (strcpy, (dst0, src0),
char *dst0 _AND
_CONST char *src0)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *s = dst0;
while (*dst0++ = *src0++)
;
return s;
#else
char *dst = dst0;
_CONST char *src = src0;
long *aligned_dst;
_CONST long *aligned_src;
/* If SRC or DEST is unaligned, then copy bytes. */
if (!UNALIGNED (src, dst))
{
aligned_dst = (long*)dst;
aligned_src = (long*)src;
/* SRC and DEST are both "long int" aligned, try to do "long int"
sized copies. */
while (!DETECTNULL(*aligned_src))
{
*aligned_dst++ = *aligned_src++;
}
dst = (char*)aligned_dst;
src = (char*)aligned_src;
}
while ((*dst++ = *src++))
;
return dst0;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

88
firmware/common/strlen.c Normal file
View file

@ -0,0 +1,88 @@
/*
FUNCTION
<<strlen>>---character string length
INDEX
strlen
ANSI_SYNOPSIS
#include <string.h>
size_t strlen(const char *<[str]>);
TRAD_SYNOPSIS
#include <string.h>
size_t strlen(<[str]>)
char *<[src]>;
DESCRIPTION
The <<strlen>> function works out the length of the string
starting at <<*<[str]>>> by counting chararacters until it
reaches a <<NULL>> character.
RETURNS
<<strlen>> returns the character count.
PORTABILITY
<<strlen>> is ANSI C.
<<strlen>> requires no supporting OS subroutines.
QUICKREF
strlen ansi pure
*/
#include <_ansi.h>
#include <string.h>
#include <limits.h>
#define LBLOCKSIZE (sizeof (long))
#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
size_t
_DEFUN (strlen, (str),
_CONST char *str)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
_CONST char *start = str;
while (*str)
str++;
return str - start;
#else
_CONST char *start = str;
unsigned long *aligned_addr;
if (!UNALIGNED (str))
{
/* If the string is word-aligned, we can check for the presence of
a null in each word-sized block. */
aligned_addr = (unsigned long*)str;
while (!DETECTNULL (*aligned_addr))
aligned_addr++;
/* Once a null is detected, we check each byte in that block for a
precise position of the null. */
str = (char*)aligned_addr;
}
while (*str)
str++;
return str - start;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

122
firmware/common/strncmp.c Normal file
View file

@ -0,0 +1,122 @@
/*
FUNCTION
<<strncmp>>---character string compare
INDEX
strncmp
ANSI_SYNOPSIS
#include <string.h>
int strncmp(const char *<[a]>, const char * <[b]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.h>
int strncmp(<[a]>, <[b]>, <[length]>)
char *<[a]>;
char *<[b]>;
size_t <[length]>
DESCRIPTION
<<strncmp>> compares up to <[length]> characters
from the string at <[a]> to the string at <[b]>.
RETURNS
If <<*<[a]>>> sorts lexicographically after <<*<[b]>>>,
<<strncmp>> returns a number greater than zero. If the two
strings are equivalent, <<strncmp>> returns zero. If <<*<[a]>>>
sorts lexicographically before <<*<[b]>>>, <<strncmp>> returns a
number less than zero.
PORTABILITY
<<strncmp>> is ANSI C.
<<strncmp>> requires no supporting OS subroutines.
QUICKREF
strncmp ansi pure
*/
#include <string.h>
#include <limits.h>
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
/* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
int
_DEFUN (strncmp, (s1, s2, n),
_CONST char *s1 _AND
_CONST char *s2 _AND
size_t n)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
if (n == 0)
return 0;
while (n-- != 0 && *s1 == *s2)
{
if (n == 0 || *s1 == '\0')
break;
s1++;
s2++;
}
return (*(unsigned char *) s1) - (*(unsigned char *) s2);
#else
unsigned long *a1;
unsigned long *a2;
if (n == 0)
return 0;
/* If s1 or s2 are unaligned, then compare bytes. */
if (!UNALIGNED (s1, s2))
{
/* If s1 and s2 are word-aligned, compare them a word at a time. */
a1 = (unsigned long*)s1;
a2 = (unsigned long*)s2;
while (n >= sizeof (long) && *a1 == *a2)
{
n -= sizeof (long);
/* If we've run out of bytes or hit a null, return zero
since we already know *a1 == *a2. */
if (n == 0 || DETECTNULL (*a1))
return 0;
a1++;
a2++;
}
/* A difference was detected in last few bytes of s1, so search bytewise */
s1 = (char*)a1;
s2 = (char*)a2;
}
while (n-- > 0 && *s1 == *s2)
{
/* If we've run out of bytes or hit a null, return zero
since we already know *s1 == *s2. */
if (n == 0 || *s1 == '\0')
return 0;
s1++;
s2++;
}
return (*(unsigned char *) s1) - (*(unsigned char *) s2);
#endif /* not PREFER_SIZE_OVER_SPEED */
}

125
firmware/common/strncpy.c Normal file
View file

@ -0,0 +1,125 @@
/*
FUNCTION
<<strncpy>>---counted copy string
INDEX
strncpy
ANSI_SYNOPSIS
#include <string.h>
char *strncpy(char *<[dst]>, const char *<[src]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.h>
char *strncpy(<[dst]>, <[src]>, <[length]>)
char *<[dst]>;
char *<[src]>;
size_t <[length]>;
DESCRIPTION
<<strncpy>> copies not more than <[length]> characters from the
the string pointed to by <[src]> (including the terminating
null character) to the array pointed to by <[dst]>. If the
string pointed to by <[src]> is shorter than <[length]>
characters, null characters are appended to the destination
array until a total of <[length]> characters have been
written.
RETURNS
This function returns the initial value of <[dst]>.
PORTABILITY
<<strncpy>> is ANSI C.
<<strncpy>> requires no supporting OS subroutines.
QUICKREF
strncpy ansi pure
*/
#include <string.h>
#include <limits.h>
/*SUPPRESS 560*/
/*SUPPRESS 530*/
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
#define TOO_SMALL(LEN) ((LEN) < sizeof (long))
char *
_DEFUN (strncpy, (dst0, src0),
char *dst0 _AND
_CONST char *src0 _AND
size_t count)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *dscan;
_CONST char *sscan;
dscan = dst0;
sscan = src0;
while (count > 0)
{
--count;
if ((*dscan++ = *sscan++) == '\0')
break;
}
while (count-- > 0)
*dscan++ = '\0';
return dst0;
#else
char *dst = dst0;
_CONST char *src = src0;
long *aligned_dst;
_CONST long *aligned_src;
/* If SRC and DEST is aligned and count large enough, then copy words. */
if (!UNALIGNED (src, dst) && !TOO_SMALL (count))
{
aligned_dst = (long*)dst;
aligned_src = (long*)src;
/* SRC and DEST are both "long int" aligned, try to do "long int"
sized copies. */
while (count >= sizeof (long int) && !DETECTNULL(*aligned_src))
{
count -= sizeof (long int);
*aligned_dst++ = *aligned_src++;
}
dst = (char*)aligned_dst;
src = (char*)aligned_src;
}
while (count > 0)
{
--count;
if ((*dst++ = *src++) == '\0')
break;
}
while (count-- > 0)
*dst++ = '\0';
return dst0;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

59
firmware/common/strrchr.c Normal file
View file

@ -0,0 +1,59 @@
/*
FUNCTION
<<strrchr>>---reverse search for character in string
INDEX
strrchr
ANSI_SYNOPSIS
#include <string.h>
char * strrchr(const char *<[string]>, int <[c]>);
TRAD_SYNOPSIS
#include <string.h>
char * strrchr(<[string]>, <[c]>);
char *<[string]>;
int *<[c]>;
DESCRIPTION
This function finds the last occurence of <[c]> (converted to
a char) in the string pointed to by <[string]> (including the
terminating null character).
RETURNS
Returns a pointer to the located character, or a null pointer
if <[c]> does not occur in <[string]>.
PORTABILITY
<<strrchr>> is ANSI C.
<<strrchr>> requires no supporting OS subroutines.
QUICKREF
strrchr ansi pure
*/
#include <string.h>
char *
_DEFUN (strrchr, (s, i),
_CONST char *s _AND
int i)
{
_CONST char *last = NULL;
if (i)
{
while ((s=strchr(s, i)))
{
last = s;
s++;
}
}
else
{
last = strchr(s, i);
}
return (char *) last;
}