Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4873 → Rev 4874

/contrib/sdk/sources/newlib/libc/string/local.h
0,0 → 1,9
#include <_ansi.h>
#include <../ctype/local.h>
 
/* internal function to compute width of wide char. */
int _EXFUN (__wcwidth, (wint_t));
 
/* Defined in locale/locale.c. Returns a value != 0 if the current
language is assumed to use CJK fonts. */
int __locale_cjk_lang ();
/contrib/sdk/sources/newlib/libc/string/memchr.c
0,0 → 1,134
/*
FUNCTION
<<memchr>>---find character in memory
 
INDEX
memchr
 
ANSI_SYNOPSIS
#include <string.h>
void *memchr(const void *<[src]>, int <[c]>, size_t <[length]>);
 
TRAD_SYNOPSIS
#include <string.h>
void *memchr(<[src]>, <[c]>, <[length]>)
void *<[src]>;
void *<[c]>;
size_t <[length]>;
 
DESCRIPTION
This function searches memory starting at <<*<[src]>>> for the
character <[c]>. The search only ends with the first
occurrence of <[c]>, or after <[length]> characters; in
particular, <<NUL>> does not terminate the search.
 
RETURNS
If the character <[c]> is found within <[length]> characters
of <<*<[src]>>>, a pointer to the character is returned. If
<[c]> is not found, then <<NULL>> is returned.
 
PORTABILITY
<<memchr>> is ANSI C.
 
<<memchr>> requires no supporting OS subroutines.
 
QUICKREF
memchr ansi pure
*/
 
#include <_ansi.h>
#include <string.h>
#include <limits.h>
 
/* Nonzero if either X or Y 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))
 
/* Threshhold for punting to the bytewise iterator. */
#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
 
#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
 
/* DETECTCHAR returns nonzero if (long)X contains the byte used
to fill (long)MASK. */
#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK))
 
_PTR
_DEFUN (memchr, (src_void, c, length),
_CONST _PTR src_void _AND
int c _AND
size_t length)
{
_CONST unsigned char *src = (_CONST unsigned char *) src_void;
unsigned char d = c;
 
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
unsigned long *asrc;
unsigned long mask;
int i;
 
while (UNALIGNED (src))
{
if (!length--)
return NULL;
if (*src == d)
return (void *) src;
src++;
}
 
if (!TOO_SMALL (length))
{
/* If we get this far, we know that length is large and src is
word-aligned. */
/* The fast code reads the source one word at a time and only
performs the bytewise search on word-sized segments if they
contain the search character, which is detected by XORing
the word-sized segment with a word-sized block of the search
character and then detecting for the presence of NUL in the
result. */
asrc = (unsigned long *) src;
mask = d << 8 | d;
mask = mask << 16 | mask;
for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
mask = (mask << i) | mask;
 
while (length >= LBLOCKSIZE)
{
if (DETECTCHAR (*asrc, mask))
break;
length -= LBLOCKSIZE;
asrc++;
}
 
/* If there are fewer than LBLOCKSIZE characters left,
then we resort to the bytewise loop. */
 
src = (unsigned char *) asrc;
}
 
#endif /* not PREFER_SIZE_OVER_SPEED */
 
while (length--)
{
if (*src == d)
return (void *) src;
src++;
}
 
return NULL;
}
/contrib/sdk/sources/newlib/libc/string/memcmp.c
0,0 → 1,113
/*
FUNCTION
<<memcmp>>---compare two memory areas
 
INDEX
memcmp
 
ANSI_SYNOPSIS
#include <string.h>
int memcmp(const void *<[s1]>, const void *<[s2]>, size_t <[n]>);
 
TRAD_SYNOPSIS
#include <string.h>
int memcmp(<[s1]>, <[s2]>, <[n]>)
void *<[s1]>;
void *<[s2]>;
size_t <[n]>;
 
DESCRIPTION
This function compares not more than <[n]> characters of the
object pointed to by <[s1]> with the object pointed to by <[s2]>.
 
 
RETURNS
The function returns an integer greater than, equal to or
less than zero according to whether the object pointed to by
<[s1]> is greater than, equal to or less than the object
pointed to by <[s2]>.
 
PORTABILITY
<<memcmp>> is ANSI C.
 
<<memcmp>> requires no supporting OS subroutines.
 
QUICKREF
memcmp ansi pure
*/
 
#include <string.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 word copy loop. */
#define LBLOCKSIZE (sizeof (long))
 
/* Threshhold for punting to the byte copier. */
#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
 
int
_DEFUN (memcmp, (m1, m2, n),
_CONST _PTR m1 _AND
_CONST _PTR m2 _AND
size_t n)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
unsigned char *s1 = (unsigned char *) m1;
unsigned char *s2 = (unsigned char *) m2;
 
while (n--)
{
if (*s1 != *s2)
{
return *s1 - *s2;
}
s1++;
s2++;
}
return 0;
#else
unsigned char *s1 = (unsigned char *) m1;
unsigned char *s2 = (unsigned char *) m2;
unsigned long *a1;
unsigned long *a2;
 
/* If the size is too small, or either pointer is unaligned,
then we punt to the byte compare loop. Hopefully this will
not turn up in inner loops. */
if (!TOO_SMALL(n) && !UNALIGNED(s1,s2))
{
/* Otherwise, load and compare the blocks of memory one
word at a time. */
a1 = (unsigned long*) s1;
a2 = (unsigned long*) s2;
while (n >= LBLOCKSIZE)
{
if (*a1 != *a2)
break;
a1++;
a2++;
n -= LBLOCKSIZE;
}
 
/* check m mod LBLOCKSIZE remaining characters */
 
s1 = (unsigned char*)a1;
s2 = (unsigned char*)a2;
}
 
while (n--)
{
if (*s1 != *s2)
return *s1 - *s2;
s1++;
s2++;
}
 
return 0;
#endif /* not PREFER_SIZE_OVER_SPEED */
}
 
/contrib/sdk/sources/newlib/libc/string/memcpy.c
0,0 → 1,110
/*
FUNCTION
<<memcpy>>---copy memory regions
 
ANSI_SYNOPSIS
#include <string.h>
void* memcpy(void *<[out]>, const void *<[in]>, size_t <[n]>);
 
TRAD_SYNOPSIS
#include <string.h>
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 <string.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;
 
/* 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(len0) && !UNALIGNED (src, dst))
{
aligned_dst = (long*)dst;
aligned_src = (long*)src;
 
/* Copy 4X long words at a time if possible. */
while (len0 >= BIGBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
len0 -= BIGBLOCKSIZE;
}
 
/* Copy one long word at a time if possible. */
while (len0 >= LITTLEBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
len0 -= LITTLEBLOCKSIZE;
}
 
/* Pick up any residual with a byte copier. */
dst = (char*)aligned_dst;
src = (char*)aligned_src;
}
 
while (len0--)
*dst++ = *src++;
 
return dst0;
#endif /* not PREFER_SIZE_OVER_SPEED */
}
/contrib/sdk/sources/newlib/libc/string/memmove.c
0,0 → 1,142
/*
FUNCTION
<<memmove>>---move possibly overlapping memory
 
INDEX
memmove
 
ANSI_SYNOPSIS
#include <string.h>
void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
 
TRAD_SYNOPSIS
#include <string.h>
void *memmove(<[dst]>, <[src]>, <[length]>)
void *<[dst]>;
void *<[src]>;
size_t <[length]>;
 
DESCRIPTION
This function moves <[length]> characters from the block of
memory starting at <<*<[src]>>> to the memory starting at
<<*<[dst]>>>. <<memmove>> reproduces the characters correctly
at <<*<[dst]>>> even if the two areas overlap.
 
 
RETURNS
The function returns <[dst]> as passed.
 
PORTABILITY
<<memmove>> is ANSI C.
 
<<memmove>> requires no supporting OS subroutines.
 
QUICKREF
memmove ansi pure
*/
 
#include <string.h>
#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)
 
/*SUPPRESS 20*/
_PTR
_DEFUN (memmove, (dst_void, src_void, length),
_PTR dst_void _AND
_CONST _PTR src_void _AND
size_t length)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *dst = dst_void;
_CONST char *src = src_void;
 
if (src < dst && dst < src + length)
{
/* Have to copy backwards */
src += length;
dst += length;
while (length--)
{
*--dst = *--src;
}
}
else
{
while (length--)
{
*dst++ = *src++;
}
}
 
return dst_void;
#else
char *dst = dst_void;
_CONST char *src = src_void;
long *aligned_dst;
_CONST long *aligned_src;
 
if (src < dst && dst < src + length)
{
/* Destructive overlap...have to copy backwards */
src += length;
dst += length;
while (length--)
{
*--dst = *--src;
}
}
else
{
/* Use optimizing algorithm for a non-destructive copy to closely
match memcpy. 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(length) && !UNALIGNED (src, dst))
{
aligned_dst = (long*)dst;
aligned_src = (long*)src;
 
/* Copy 4X long words at a time if possible. */
while (length >= BIGBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
length -= BIGBLOCKSIZE;
}
 
/* Copy one long word at a time if possible. */
while (length >= LITTLEBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
length -= LITTLEBLOCKSIZE;
}
 
/* Pick up any residual with a byte copier. */
dst = (char*)aligned_dst;
src = (char*)aligned_src;
}
 
while (length--)
{
*dst++ = *src++;
}
}
 
return dst_void;
#endif /* not PREFER_SIZE_OVER_SPEED */
}
/contrib/sdk/sources/newlib/libc/string/memset.c
0,0 → 1,102
/*
FUNCTION
<<memset>>---set an area of memory
 
INDEX
memset
 
ANSI_SYNOPSIS
#include <string.h>
void *memset(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 <[dst]>.
 
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)
{
char *s = (char *) m;
 
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
int i;
unsigned long buffer;
unsigned long *aligned_addr;
unsigned int d = c & 0xff; /* To avoid sign extension, copy C to an
unsigned variable. */
 
while (UNALIGNED (s))
{
if (n--)
*s++ = (char) c;
else
return m;
}
 
if (!TOO_SMALL (n))
{
/* If we get this far, we know that n is large and s is word-aligned. */
aligned_addr = (unsigned long *) s;
 
/* Store D into each char sized location in BUFFER so that
we can set large blocks quickly. */
buffer = (d << 8) | d;
buffer |= (buffer << 16);
for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
buffer = (buffer << i) | buffer;
 
/* Unroll the loop. */
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;
}
 
#endif /* not PREFER_SIZE_OVER_SPEED */
 
while (n--)
*s++ = (char) c;
 
return m;
}
/contrib/sdk/sources/newlib/libc/string/stpcpy.c
0,0 → 1,91
/*
FUNCTION
<<stpcpy>>---copy string returning a pointer to its end
 
INDEX
stpcpy
 
ANSI_SYNOPSIS
#include <string.h>
char *stpcpy(char *<[dst]>, const char *<[src]>);
 
TRAD_SYNOPSIS
#include <string.h>
char *stpcpy(<[dst]>, <[src]>)
char *<[dst]>;
char *<[src]>;
 
DESCRIPTION
<<stpcpy>> copies the string pointed to by <[src]>
(including the terminating null character) to the array
pointed to by <[dst]>.
 
RETURNS
This function returns a pointer to the end of the destination string,
thus pointing to the trailing '\0'.
 
PORTABILITY
<<stpcpy>> is a GNU extension, candidate for inclusion into POSIX/SUSv4.
 
<<stpcpy>> requires no supporting OS subroutines.
 
QUICKREF
stpcpy gnu
*/
 
#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 (stpcpy, (dst, src),
char *dst _AND
_CONST char *src)
{
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
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;
}
#endif /* not PREFER_SIZE_OVER_SPEED */
 
while ((*dst++ = *src++))
;
return --dst;
}
/contrib/sdk/sources/newlib/libc/string/stpncpy.c
0,0 → 1,114
/*
FUNCTION
<<stpncpy>>---counted copy string returning a pointer to its end
 
INDEX
stpncpy
 
ANSI_SYNOPSIS
#include <string.h>
char *stpncpy(char *<[dst]>, const char *<[src]>, size_t <[length]>);
 
TRAD_SYNOPSIS
#include <string.h>
char *stpncpy(<[dst]>, <[src]>, <[length]>)
char *<[dst]>;
char *<[src]>;
size_t <[length]>;
 
DESCRIPTION
<<stpncpy>> 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 a pointer to the end of the destination string,
thus pointing to the trailing '\0', or, if the destination string is
not null-terminated, pointing to dst + n.
 
PORTABILITY
<<stpncpy>> is a GNU extension, candidate for inclusion into POSIX/SUSv4.
 
<<stpncpy>> requires no supporting OS subroutines.
 
QUICKREF
stpncpy gnu
*/
 
#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 (stpncpy, (dst, src),
char *dst _AND
_CONST char *src _AND
size_t count)
{
char *ret = NULL;
 
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
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;
}
#endif /* not PREFER_SIZE_OVER_SPEED */
 
while (count > 0)
{
--count;
if ((*dst++ = *src++) == '\0')
{
ret = dst - 1;
break;
}
}
 
while (count-- > 0)
*dst++ = '\0';
 
return ret ? ret : dst;
}
/contrib/sdk/sources/newlib/libc/string/str-two-way.h
0,0 → 1,415
/* Byte-wise substring search, using the Two-Way algorithm.
* Copyright (C) 2008, 2010 Eric Blake
* Permission to use, copy, modify, and distribute this software
* is freely granted, provided that this notice is preserved.
*/
 
 
/* Before including this file, you need to include <string.h>, and define:
RESULT_TYPE A macro that expands to the return type.
AVAILABLE(h, h_l, j, n_l) A macro that returns nonzero if there are
at least N_L bytes left starting at
H[J]. H is 'unsigned char *', H_L, J,
and N_L are 'size_t'; H_L is an
lvalue. For NUL-terminated searches,
H_L can be modified each iteration to
avoid having to compute the end of H
up front.
 
For case-insensitivity, you may optionally define:
CMP_FUNC(p1, p2, l) A macro that returns 0 iff the first L
characters of P1 and P2 are equal.
CANON_ELEMENT(c) A macro that canonicalizes an element
right after it has been fetched from
one of the two strings. The argument
is an 'unsigned char'; the result must
be an 'unsigned char' as well.
 
This file undefines the macros documented above, and defines
LONG_NEEDLE_THRESHOLD.
*/
 
#include <limits.h>
#include <stdint.h>
 
/* We use the Two-Way string matching algorithm, which guarantees
linear complexity with constant space. Additionally, for long
needles, we also use a bad character shift table similar to the
Boyer-Moore algorithm to achieve improved (potentially sub-linear)
performance.
 
See http://www-igm.univ-mlv.fr/~lecroq/string/node26.html#SECTION00260
and http://en.wikipedia.org/wiki/Boyer-Moore_string_search_algorithm
*/
 
/* Point at which computing a bad-byte shift table is likely to be
worthwhile. Small needles should not compute a table, since it
adds (1 << CHAR_BIT) + NEEDLE_LEN computations of preparation for a
speedup no greater than a factor of NEEDLE_LEN. The larger the
needle, the better the potential performance gain. On the other
hand, on non-POSIX systems with CHAR_BIT larger than eight, the
memory required for the table is prohibitive. */
#if CHAR_BIT < 10
# define LONG_NEEDLE_THRESHOLD 32U
#else
# define LONG_NEEDLE_THRESHOLD SIZE_MAX
#endif
 
#define MAX(a, b) ((a < b) ? (b) : (a))
 
#ifndef CANON_ELEMENT
# define CANON_ELEMENT(c) c
#endif
#ifndef CMP_FUNC
# define CMP_FUNC memcmp
#endif
 
/* Perform a critical factorization of NEEDLE, of length NEEDLE_LEN.
Return the index of the first byte in the right half, and set
*PERIOD to the global period of the right half.
 
The global period of a string is the smallest index (possibly its
length) at which all remaining bytes in the string are repetitions
of the prefix (the last repetition may be a subset of the prefix).
 
When NEEDLE is factored into two halves, a local period is the
length of the smallest word that shares a suffix with the left half
and shares a prefix with the right half. All factorizations of a
non-empty NEEDLE have a local period of at least 1 and no greater
than NEEDLE_LEN.
 
A critical factorization has the property that the local period
equals the global period. All strings have at least one critical
factorization with the left half smaller than the global period.
 
Given an ordered alphabet, a critical factorization can be computed
in linear time, with 2 * NEEDLE_LEN comparisons, by computing the
larger of two ordered maximal suffixes. The ordered maximal
suffixes are determined by lexicographic comparison of
periodicity. */
static size_t
critical_factorization (const unsigned char *needle, size_t needle_len,
size_t *period)
{
/* Index of last byte of left half, or SIZE_MAX. */
size_t max_suffix, max_suffix_rev;
size_t j; /* Index into NEEDLE for current candidate suffix. */
size_t k; /* Offset into current period. */
size_t p; /* Intermediate period. */
unsigned char a, b; /* Current comparison bytes. */
 
/* Invariants:
0 <= j < NEEDLE_LEN - 1
-1 <= max_suffix{,_rev} < j (treating SIZE_MAX as if it were signed)
min(max_suffix, max_suffix_rev) < global period of NEEDLE
1 <= p <= global period of NEEDLE
p == global period of the substring NEEDLE[max_suffix{,_rev}+1...j]
1 <= k <= p
*/
 
/* Perform lexicographic search. */
max_suffix = SIZE_MAX;
j = 0;
k = p = 1;
while (j + k < needle_len)
{
a = CANON_ELEMENT (needle[j + k]);
b = CANON_ELEMENT (needle[(size_t)(max_suffix + k)]);
if (a < b)
{
/* Suffix is smaller, period is entire prefix so far. */
j += k;
k = 1;
p = j - max_suffix;
}
else if (a == b)
{
/* Advance through repetition of the current period. */
if (k != p)
++k;
else
{
j += p;
k = 1;
}
}
else /* b < a */
{
/* Suffix is larger, start over from current location. */
max_suffix = j++;
k = p = 1;
}
}
*period = p;
 
/* Perform reverse lexicographic search. */
max_suffix_rev = SIZE_MAX;
j = 0;
k = p = 1;
while (j + k < needle_len)
{
a = CANON_ELEMENT (needle[j + k]);
b = CANON_ELEMENT (needle[max_suffix_rev + k]);
if (b < a)
{
/* Suffix is smaller, period is entire prefix so far. */
j += k;
k = 1;
p = j - max_suffix_rev;
}
else if (a == b)
{
/* Advance through repetition of the current period. */
if (k != p)
++k;
else
{
j += p;
k = 1;
}
}
else /* a < b */
{
/* Suffix is larger, start over from current location. */
max_suffix_rev = j++;
k = p = 1;
}
}
 
/* Choose the longer suffix. Return the first byte of the right
half, rather than the last byte of the left half. */
if (max_suffix_rev + 1 < max_suffix + 1)
return max_suffix + 1;
*period = p;
return max_suffix_rev + 1;
}
 
/* Return the first location of non-empty NEEDLE within HAYSTACK, or
NULL. HAYSTACK_LEN is the minimum known length of HAYSTACK. This
method is optimized for NEEDLE_LEN < LONG_NEEDLE_THRESHOLD.
Performance is guaranteed to be linear, with an initialization cost
of 2 * NEEDLE_LEN comparisons.
 
If AVAILABLE does not modify HAYSTACK_LEN (as in memmem), then at
most 2 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching.
If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 *
HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching. */
static RETURN_TYPE
two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
const unsigned char *needle, size_t needle_len)
{
size_t i; /* Index into current byte of NEEDLE. */
size_t j; /* Index into current window of HAYSTACK. */
size_t period; /* The period of the right half of needle. */
size_t suffix; /* The index of the right half of needle. */
 
/* Factor the needle into two halves, such that the left half is
smaller than the global period, and the right half is
periodic (with a period as large as NEEDLE_LEN - suffix). */
suffix = critical_factorization (needle, needle_len, &period);
 
/* Perform the search. Each iteration compares the right half
first. */
if (CMP_FUNC (needle, needle + period, suffix) == 0)
{
/* Entire needle is periodic; a mismatch can only advance by the
period, so use memory to avoid rescanning known occurrences
of the period. */
size_t memory = 0;
j = 0;
while (AVAILABLE (haystack, haystack_len, j, needle_len))
{
/* Scan for matches in right half. */
i = MAX (suffix, memory);
while (i < needle_len && (CANON_ELEMENT (needle[i])
== CANON_ELEMENT (haystack[i + j])))
++i;
if (needle_len <= i)
{
/* Scan for matches in left half. */
i = suffix - 1;
while (memory < i + 1 && (CANON_ELEMENT (needle[i])
== CANON_ELEMENT (haystack[i + j])))
--i;
if (i + 1 < memory + 1)
return (RETURN_TYPE) (haystack + j);
/* No match, so remember how many repetitions of period
on the right half were scanned. */
j += period;
memory = needle_len - period;
}
else
{
j += i - suffix + 1;
memory = 0;
}
}
}
else
{
/* The two halves of needle are distinct; no extra memory is
required, and any mismatch results in a maximal shift. */
period = MAX (suffix, needle_len - suffix) + 1;
j = 0;
while (AVAILABLE (haystack, haystack_len, j, needle_len))
{
/* Scan for matches in right half. */
i = suffix;
while (i < needle_len && (CANON_ELEMENT (needle[i])
== CANON_ELEMENT (haystack[i + j])))
++i;
if (needle_len <= i)
{
/* Scan for matches in left half. */
i = suffix - 1;
while (i != SIZE_MAX && (CANON_ELEMENT (needle[i])
== CANON_ELEMENT (haystack[i + j])))
--i;
if (i == SIZE_MAX)
return (RETURN_TYPE) (haystack + j);
j += period;
}
else
j += i - suffix + 1;
}
}
return NULL;
}
 
/* Return the first location of non-empty NEEDLE within HAYSTACK, or
NULL. HAYSTACK_LEN is the minimum known length of HAYSTACK. This
method is optimized for LONG_NEEDLE_THRESHOLD <= NEEDLE_LEN.
Performance is guaranteed to be linear, with an initialization cost
of 3 * NEEDLE_LEN + (1 << CHAR_BIT) operations.
 
If AVAILABLE does not modify HAYSTACK_LEN (as in memmem), then at
most 2 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching,
and sublinear performance O(HAYSTACK_LEN / NEEDLE_LEN) is possible.
If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 *
HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching, and
sublinear performance is not possible. */
static RETURN_TYPE
two_way_long_needle (const unsigned char *haystack, size_t haystack_len,
const unsigned char *needle, size_t needle_len)
{
size_t i; /* Index into current byte of NEEDLE. */
size_t j; /* Index into current window of HAYSTACK. */
size_t period; /* The period of the right half of needle. */
size_t suffix; /* The index of the right half of needle. */
size_t shift_table[1U << CHAR_BIT]; /* See below. */
 
/* Factor the needle into two halves, such that the left half is
smaller than the global period, and the right half is
periodic (with a period as large as NEEDLE_LEN - suffix). */
suffix = critical_factorization (needle, needle_len, &period);
 
/* Populate shift_table. For each possible byte value c,
shift_table[c] is the distance from the last occurrence of c to
the end of NEEDLE, or NEEDLE_LEN if c is absent from the NEEDLE.
shift_table[NEEDLE[NEEDLE_LEN - 1]] contains the only 0. */
for (i = 0; i < 1U << CHAR_BIT; i++)
shift_table[i] = needle_len;
for (i = 0; i < needle_len; i++)
shift_table[CANON_ELEMENT (needle[i])] = needle_len - i - 1;
 
/* Perform the search. Each iteration compares the right half
first. */
if (CMP_FUNC (needle, needle + period, suffix) == 0)
{
/* Entire needle is periodic; a mismatch can only advance by the
period, so use memory to avoid rescanning known occurrences
of the period. */
size_t memory = 0;
size_t shift;
j = 0;
while (AVAILABLE (haystack, haystack_len, j, needle_len))
{
/* Check the last byte first; if it does not match, then
shift to the next possible match location. */
shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])];
if (0 < shift)
{
if (memory && shift < period)
{
/* Since needle is periodic, but the last period has
a byte out of place, there can be no match until
after the mismatch. */
shift = needle_len - period;
}
memory = 0;
j += shift;
continue;
}
/* Scan for matches in right half. The last byte has
already been matched, by virtue of the shift table. */
i = MAX (suffix, memory);
while (i < needle_len - 1 && (CANON_ELEMENT (needle[i])
== CANON_ELEMENT (haystack[i + j])))
++i;
if (needle_len - 1 <= i)
{
/* Scan for matches in left half. */
i = suffix - 1;
while (memory < i + 1 && (CANON_ELEMENT (needle[i])
== CANON_ELEMENT (haystack[i + j])))
--i;
if (i + 1 < memory + 1)
return (RETURN_TYPE) (haystack + j);
/* No match, so remember how many repetitions of period
on the right half were scanned. */
j += period;
memory = needle_len - period;
}
else
{
j += i - suffix + 1;
memory = 0;
}
}
}
else
{
/* The two halves of needle are distinct; no extra memory is
required, and any mismatch results in a maximal shift. */
size_t shift;
period = MAX (suffix, needle_len - suffix) + 1;
j = 0;
while (AVAILABLE (haystack, haystack_len, j, needle_len))
{
/* Check the last byte first; if it does not match, then
shift to the next possible match location. */
shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])];
if (0 < shift)
{
j += shift;
continue;
}
/* Scan for matches in right half. The last byte has
already been matched, by virtue of the shift table. */
i = suffix;
while (i < needle_len - 1 && (CANON_ELEMENT (needle[i])
== CANON_ELEMENT (haystack[i + j])))
++i;
if (needle_len - 1 <= i)
{
/* Scan for matches in left half. */
i = suffix - 1;
while (i != SIZE_MAX && (CANON_ELEMENT (needle[i])
== CANON_ELEMENT (haystack[i + j])))
--i;
if (i == SIZE_MAX)
return (RETURN_TYPE) (haystack + j);
j += period;
}
else
j += i - suffix + 1;
}
}
return NULL;
}
 
#undef AVAILABLE
#undef CANON_ELEMENT
#undef CMP_FUNC
#undef MAX
#undef RETURN_TYPE
/contrib/sdk/sources/newlib/libc/string/strcasecmp.c
0,0 → 1,60
/*
FUNCTION
<<strcasecmp>>---case-insensitive character string compare
INDEX
strcasecmp
 
ANSI_SYNOPSIS
#include <strings.h>
int strcasecmp(const char *<[a]>, const char *<[b]>);
 
TRAD_SYNOPSIS
#include <strings.h>
int strcasecmp(<[a]>, <[b]>)
char *<[a]>;
char *<[b]>;
 
DESCRIPTION
<<strcasecmp>> compares the string at <[a]> to
the string at <[b]> in a case-insensitive manner.
 
RETURNS
 
If <<*<[a]>>> sorts lexicographically after <<*<[b]>>> (after
both are converted to lowercase), <<strcasecmp>> returns a
number greater than zero. If the two strings match,
<<strcasecmp>> returns zero. If <<*<[a]>>> sorts
lexicographically before <<*<[b]>>>, <<strcasecmp>> returns a
number less than zero.
 
PORTABILITY
<<strcasecmp>> is in the Berkeley Software Distribution.
 
<<strcasecmp>> requires no supporting OS subroutines. It uses
tolower() from elsewhere in this library.
 
QUICKREF
strcasecmp
*/
 
#include <strings.h>
#include <ctype.h>
 
int
_DEFUN (strcasecmp, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
_CONST unsigned char *ucs1 = (_CONST unsigned char *) s1;
_CONST unsigned char *ucs2 = (_CONST unsigned char *) s2;
int d = 0;
for ( ; ; )
{
_CONST int c1 = tolower(*ucs1++);
_CONST int c2 = tolower(*ucs2++);
if (((d = c1 - c2) != 0) || (c2 == '\0'))
break;
}
return d;
}
/contrib/sdk/sources/newlib/libc/string/strcasestr.c
0,0 → 1,148
/*
FUNCTION
<<strcasestr>>---case-insensitive character string search
 
INDEX
strcasestr
 
ANSI_SYNOPSIS
#include <string.h>
char *strcasestr(const char *<[s]>, const char *<[find]>);
 
TRAD_SYNOPSIS
#include <string.h>
int strcasecmp(<[s]>, <[find]>)
char *<[s]>;
char *<[find]>;
 
DESCRIPTION
<<strcasestr>> searchs the string <[s]> for
the first occurrence of the sequence <[find]>. <<strcasestr>>
is identical to <<strstr>> except the search is
case-insensitive.
 
RETURNS
 
A pointer to the first case-insensitive occurrence of the sequence
<[find]> or <<NULL>> if no match was found.
 
PORTABILITY
<<strcasestr>> is in the Berkeley Software Distribution.
 
<<strcasestr>> requires no supporting OS subroutines. It uses
tolower() from elsewhere in this library.
 
QUICKREF
strcasestr
*/
 
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* The quadratic code is derived from software contributed to Berkeley by
* Chris Torek.
*
* 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.
* 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.
*/
/* Linear algorithm Copyright (C) 2008 Eric Blake
* Permission to use, copy, modify, and distribute the linear portion of
* software is freely granted, provided that this notice is preserved.
*/
 
#include <sys/cdefs.h>
 
#include <ctype.h>
#include <string.h>
#include <strings.h>
 
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
# define RETURN_TYPE char *
# define AVAILABLE(h, h_l, j, n_l) \
(!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \
&& ((h_l) = (j) + (n_l)))
# define CANON_ELEMENT(c) tolower (c)
# define CMP_FUNC strncasecmp
# include "str-two-way.h"
#endif
 
/*
* Find the first occurrence of find in s, ignore case.
*/
char *
strcasestr(s, find)
const char *s, *find;
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
 
/* Less code size, but quadratic performance in the worst case. */
char c, sc;
size_t len;
 
if ((c = *find++) != 0) {
c = tolower((unsigned char)c);
len = strlen(find);
do {
do {
if ((sc = *s++) == 0)
return (NULL);
} while ((char)tolower((unsigned char)sc) != c);
} while (strncasecmp(s, find, len) != 0);
s--;
}
return ((char *)s);
 
#else /* compilation for speed */
 
/* Larger code size, but guaranteed linear performance. */
const char *haystack = s;
const char *needle = find;
size_t needle_len; /* Length of NEEDLE. */
size_t haystack_len; /* Known minimum length of HAYSTACK. */
int ok = 1; /* True if NEEDLE is prefix of HAYSTACK. */
 
/* Determine length of NEEDLE, and in the process, make sure
HAYSTACK is at least as long (no point processing all of a long
NEEDLE if HAYSTACK is too short). */
while (*haystack && *needle)
ok &= (tolower ((unsigned char) *haystack++)
== tolower ((unsigned char) *needle++));
if (*needle)
return NULL;
if (ok)
return (char *) s;
needle_len = needle - find;
haystack = s + 1;
haystack_len = needle_len - 1;
 
/* Perform the search. */
if (needle_len < LONG_NEEDLE_THRESHOLD)
return two_way_short_needle ((const unsigned char *) haystack,
haystack_len,
(const unsigned char *) find, needle_len);
return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
(const unsigned char *) find, needle_len);
#endif /* compilation for speed */
}
/contrib/sdk/sources/newlib/libc/string/strcat.c
0,0 → 1,104
/*
FUNCTION
<<strcat>>---concatenate strings
 
INDEX
strcat
 
ANSI_SYNOPSIS
#include <string.h>
char *strcat(char *<[dst]>, const char *<[src]>);
 
TRAD_SYNOPSIS
#include <string.h>
char *strcat(<[dst]>, <[src]>)
char *<[dst]>;
char *<[src]>;
 
DESCRIPTION
<<strcat>> appends a copy of the string pointed to by <[src]>
(including the terminating null character) to the end of the
string pointed to by <[dst]>. The initial character of
<[src]> overwrites the null character at the end of <[dst]>.
 
RETURNS
This function returns the initial value of <[dst]>
 
PORTABILITY
<<strcat>> is ANSI C.
 
<<strcat>> requires no supporting OS subroutines.
 
QUICKREF
strcat ansi pure
*/
 
#include <string.h>
#include <limits.h>
 
/* Nonzero if X is aligned on a "long" boundary. */
#define ALIGNED(X) \
(((long)X & (sizeof (long) - 1)) == 0)
 
#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
 
 
/*SUPPRESS 560*/
/*SUPPRESS 530*/
 
char *
_DEFUN (strcat, (s1, s2),
char *s1 _AND
_CONST char *s2)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *s = s1;
 
while (*s1)
s1++;
 
while (*s1++ = *s2++)
;
return s;
#else
char *s = s1;
 
 
/* Skip over the data in s1 as quickly as possible. */
if (ALIGNED (s1))
{
unsigned long *aligned_s1 = (unsigned long *)s1;
while (!DETECTNULL (*aligned_s1))
aligned_s1++;
 
s1 = (char *)aligned_s1;
}
 
while (*s1)
s1++;
 
/* s1 now points to the its trailing null character, we can
just use strcpy to do the work for us now.
 
?!? We might want to just include strcpy here.
Also, this will cause many more unaligned string copies because
s1 is much less likely to be aligned. I don't know if its worth
tweaking strcpy to handle this better. */
strcpy (s1, s2);
return s;
#endif /* not PREFER_SIZE_OVER_SPEED */
}
/contrib/sdk/sources/newlib/libc/string/strchr.c
0,0 → 1,123
/*
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]>);
const 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;
unsigned char c = i;
 
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
unsigned long mask,j;
unsigned long *aligned_addr;
 
/* Special case for finding 0. */
if (!c)
{
while (UNALIGNED (s))
{
if (!*s)
return (char *) s;
s++;
}
/* Operate a word at a time. */
aligned_addr = (unsigned long *) s;
while (!DETECTNULL (*aligned_addr))
aligned_addr++;
/* Found the end of string. */
s = (const unsigned char *) aligned_addr;
while (*s)
s++;
return (char *) s;
}
 
/* All other bytes. Align the pointer, then search a long at a time. */
while (UNALIGNED (s))
{
if (!*s)
return NULL;
if (*s == c)
return (char *) s;
s++;
}
 
mask = c;
for (j = 8; j < LBLOCKSIZE * 8; j <<= 1)
mask = (mask << j) | mask;
 
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;
 
#endif /* not PREFER_SIZE_OVER_SPEED */
 
while (*s && *s != c)
s++;
if (*s == c)
return (char *)s;
return NULL;
}
/contrib/sdk/sources/newlib/libc/string/strcmp.c
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 */
}
/contrib/sdk/sources/newlib/libc/string/strcoll.c
0,0 → 1,48
/*
FUNCTION
<<strcoll>>---locale-specific character string compare
INDEX
strcoll
 
ANSI_SYNOPSIS
#include <string.h>
int strcoll(const char *<[stra]>, const char * <[strb]>);
 
TRAD_SYNOPSIS
#include <string.h>
int strcoll(<[stra]>, <[strb]>)
char *<[stra]>;
char *<[strb]>;
 
DESCRIPTION
<<strcoll>> compares the string pointed to by <[stra]> to
the string pointed to by <[strb]>, using an interpretation
appropriate to the current <<LC_COLLATE>> state.
 
RETURNS
If the first string is greater than the second string,
<<strcoll>> returns a number greater than zero. If the two
strings are equivalent, <<strcoll>> returns zero. If the first
string is less than the second string, <<strcoll>> returns a
number less than zero.
 
PORTABILITY
<<strcoll>> is ANSI C.
 
<<strcoll>> requires no supporting OS subroutines.
 
QUICKREF
strcoll ansi pure
*/
 
#include <string.h>
 
int
_DEFUN (strcoll, (a, b),
_CONST char *a _AND
_CONST char *b)
 
{
return strcmp (a, b);
}
/contrib/sdk/sources/newlib/libc/string/strcpy.c
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 */
}
/contrib/sdk/sources/newlib/libc/string/strcspn.c
0,0 → 1,54
/*
FUNCTION
<<strcspn>>---count characters not in string
 
INDEX
strcspn
 
ANSI_SYNOPSIS
size_t strcspn(const char *<[s1]>, const char *<[s2]>);
 
TRAD_SYNOPSIS
size_t strcspn(<[s1]>, <[s2]>)
char *<[s1]>;
char *<[s2]>;
 
DESCRIPTION
This function computes the length of the initial part of
the string pointed to by <[s1]> which consists entirely of
characters <[NOT]> from the string pointed to by <[s2]>
(excluding the terminating null character).
 
RETURNS
<<strcspn>> returns the length of the substring found.
 
PORTABILITY
<<strcspn>> is ANSI C.
 
<<strcspn>> requires no supporting OS subroutines.
*/
 
#include <string.h>
 
size_t
_DEFUN (strcspn, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
_CONST char *s = s1;
_CONST char *c;
 
while (*s1)
{
for (c = s2; *c; c++)
{
if (*s1 == *c)
break;
}
if (*c)
break;
s1++;
}
 
return s1 - s;
}
/contrib/sdk/sources/newlib/libc/string/strdup.c
0,0 → 1,13
#ifndef _REENT_ONLY
 
#include <reent.h>
#include <stdlib.h>
#include <string.h>
 
char *
_DEFUN (strdup, (str), _CONST char *str)
{
return _strdup_r (_REENT, str);
}
 
#endif /* !_REENT_ONLY */
/contrib/sdk/sources/newlib/libc/string/strdup_r.c
0,0 → 1,17
#include <reent.h>
#include <stdlib.h>
#include <string.h>
 
char *
_DEFUN (_strdup_r, (reent_ptr, str),
struct _reent *reent_ptr _AND
_CONST char *str)
{
size_t len = strlen (str) + 1;
char *copy = _malloc_r (reent_ptr, len);
if (copy)
{
memcpy (copy, str, len);
}
return copy;
}
/contrib/sdk/sources/newlib/libc/string/strerror.c
0,0 → 1,838
/***
**** CAUTION!!! KEEP DOC CONSISTENT---if you change text of a message
**** here, change two places:
**** 1) the leading doc section (alphabetized by macro)
**** 2) the real text inside switch(errnum)
***/
 
/*
FUNCTION
<<strerror>>---convert error number to string
 
INDEX
strerror
 
ANSI_SYNOPSIS
#include <string.h>
char *strerror(int <[errnum]>);
char *_strerror_r(struct _reent <[ptr]>, int <[errnum]>,
int <[internal]>, int *<[error]>);
 
TRAD_SYNOPSIS
#include <string.h>
char *strerror(<[errnum]>)
int <[errnum]>;
 
DESCRIPTION
<<strerror>> converts the error number <[errnum]> into a
string. The value of <[errnum]> is usually a copy of <<errno>>.
If <<errnum>> is not a known error number, the result points to an
empty string.
 
This implementation of <<strerror>> prints out the following strings
for each of the values defined in `<<errno.h>>':
 
o+
o 0
Success
 
o E2BIG
Arg list too long
 
o EACCES
Permission denied
 
o EADDRINUSE
Address already in use
 
o EADV
Advertise error
 
o EAFNOSUPPORT
Address family not supported by protocol family
 
o EAGAIN
No more processes
 
o EALREADY
Socket already connected
 
o EBADF
Bad file number
 
o EBADMSG
Bad message
 
o EBUSY
Device or resource busy
 
o ECHILD
No children
 
o ECOMM
Communication error
 
o ECONNABORTED
Software caused connection abort
 
o ECONNREFUSED
Connection refused
 
o EDEADLK
Deadlock
 
o EDESTADDRREQ
Destination address required
 
o EEXIST
File exists
 
o EDOM
Math argument
 
o EFAULT
Bad address
 
o EFBIG
File too large
 
o EHOSTDOWN
Host is down
 
o EHOSTUNREACH
Host is unreachable
 
o EIDRM
Identifier removed
 
o EINPROGRESS
Connection already in progress
 
o EINTR
Interrupted system call
 
o EINVAL
Invalid argument
 
o EIO
I/O error
 
o EISCONN
Socket is already connected
 
o EISDIR
Is a directory
 
o ELIBACC
Cannot access a needed shared library
 
o ELIBBAD
Accessing a corrupted shared library
 
o ELIBEXEC
Cannot exec a shared library directly
 
o ELIBMAX
Attempting to link in more shared libraries than system limit
 
o ELIBSCN
<<.lib>> section in a.out corrupted
 
o EMFILE
Too many open files
 
o EMLINK
Too many links
 
o EMSGSIZE
Message too long
 
o EMULTIHOP
Multihop attempted
 
o ENAMETOOLONG
File or path name too long
 
o ENETDOWN
Network interface not configured
 
o ENETUNREACH
Network is unreachable
 
o ENFILE
Too many open files in system
 
o ENODEV
No such device
 
o ENOENT
No such file or directory
 
o ENOEXEC
Exec format error
 
o ENOLCK
No lock
 
o ENOLINK
Virtual circuit is gone
 
o ENOMEM
Not enough space
 
o ENOMSG
No message of desired type
 
o ENONET
Machine is not on the network
 
o ENOPKG
No package
 
o ENOPROTOOPT
Protocol not available
 
o ENOSPC
No space left on device
 
o ENOSR
No stream resources
 
o ENOSTR
Not a stream
 
o ENOSYS
Function not implemented
 
o ENOTBLK
Block device required
 
o ENOTCONN
Socket is not connected
 
o ENOTDIR
Not a directory
 
o ENOTEMPTY
Directory not empty
 
o ENOTSOCK
Socket operation on non-socket
 
o ENOTSUP
Not supported
 
o ENOTTY
Not a character device
 
o ENXIO
No such device or address
 
o EPERM
Not owner
 
o EPIPE
Broken pipe
 
o EPROTO
Protocol error
 
o EPROTOTYPE
Protocol wrong type for socket
 
o EPROTONOSUPPORT
Unknown protocol
 
o ERANGE
Result too large
 
o EREMOTE
Resource is remote
 
o EROFS
Read-only file system
 
o ESHUTDOWN
Can't send after socket shutdown
 
o ESOCKTNOSUPPORT
Socket type not supported
 
o ESPIPE
Illegal seek
 
o ESRCH
No such process
 
o ESRMNT
Srmount error
 
o ETIME
Stream ioctl timeout
 
o ETIMEDOUT
Connection timed out
 
o ETXTBSY
Text file busy
 
o EXDEV
Cross-device link
 
o ECANCELED
Operation canceled
 
o ENOTRECOVERABLE
State not recoverable
 
o EOWNERDEAD
Previous owner died
 
o ESTRPIPE
Strings pipe error
 
o-
 
<<_strerror_r>> is a reentrant version of the above.
 
RETURNS
This function returns a pointer to a string. Your application must
not modify that string.
 
PORTABILITY
ANSI C requires <<strerror>>, but does not specify the strings used
for each error number.
 
Although this implementation of <<strerror>> is reentrant (depending
on <<_user_strerror>>), ANSI C declares that subsequent calls to
<<strerror>> may overwrite the result string; therefore portable
code cannot depend on the reentrancy of this subroutine.
 
Although this implementation of <<strerror>> guarantees a non-null
result with a NUL-terminator, some implementations return <<NULL>>
on failure. Although POSIX allows <<strerror>> to set <<errno>>
to EINVAL on failure, this implementation does not do so (unless
you provide <<_user_strerror>>).
 
POSIX recommends that unknown <[errnum]> result in a message
including that value, however it is not a requirement and this
implementation does not provide that information (unless you
provide <<_user_strerror>>).
 
This implementation of <<strerror>> provides for user-defined
extensibility. <<errno.h>> defines <[__ELASTERROR]>, which can be
used as a base for user-defined error values. If the user supplies a
routine named <<_user_strerror>>, and <[errnum]> passed to
<<strerror>> does not match any of the supported values,
<<_user_strerror>> is called with three arguments. The first is of
type <[int]>, and is the <[errnum]> value unknown to <<strerror>>.
The second is of type <[int]>, and matches the <[internal]> argument
of <<_strerror_r>>; this should be zero if called from <<strerror>>
and non-zero if called from any other function; <<_user_strerror>> can
use this information to satisfy the POSIX rule that no other
standardized function can overwrite a static buffer reused by
<<strerror>>. The third is of type <[int *]>, and matches the
<[error]> argument of <<_strerror_r>>; if a non-zero value is stored
into that location (usually <[EINVAL]>), then <<strerror>> will set
<<errno>> to that value, and the XPG variant of <<strerror_r>> will
return that value instead of zero or <[ERANGE]>. <<_user_strerror>>
returns a <[char *]> value; returning <[NULL]> implies that the user
function did not choose to handle <[errnum]>. The default
<<_user_strerror>> returns <[NULL]> for all input values. Note that
<<_user_sterror>> must be thread-safe, and only denote errors via the
third argument rather than modifying <<errno>>, if <<strerror>> and
<<strerror_r>> are are to comply with POSIX.
 
<<strerror>> requires no supporting OS subroutines.
 
QUICKREF
strerror ansi pure
*/
 
#include <errno.h>
#include <string.h>
 
char *
_DEFUN (_strerror_r, (ptr, errnum, internal, errptr),
struct _reent *ptr _AND
int errnum _AND
int internal _AND
int *errptr)
{
char *error;
extern char *_user_strerror _PARAMS ((int, int, int *));
 
switch (errnum)
{
case 0:
error = "Success";
break;
/* go32 defines EPERM as EACCES */
#if defined (EPERM) && (!defined (EACCES) || (EPERM != EACCES))
case EPERM:
error = "Not owner";
break;
#endif
#ifdef ENOENT
case ENOENT:
error = "No such file or directory";
break;
#endif
#ifdef ESRCH
case ESRCH:
error = "No such process";
break;
#endif
#ifdef EINTR
case EINTR:
error = "Interrupted system call";
break;
#endif
#ifdef EIO
case EIO:
error = "I/O error";
break;
#endif
/* go32 defines ENXIO as ENODEV */
#if defined (ENXIO) && (!defined (ENODEV) || (ENXIO != ENODEV))
case ENXIO:
error = "No such device or address";
break;
#endif
#ifdef E2BIG
case E2BIG:
error = "Arg list too long";
break;
#endif
#ifdef ENOEXEC
case ENOEXEC:
error = "Exec format error";
break;
#endif
#ifdef EALREADY
case EALREADY:
error = "Socket already connected";
break;
#endif
#ifdef EBADF
case EBADF:
error = "Bad file number";
break;
#endif
#ifdef ECHILD
case ECHILD:
error = "No children";
break;
#endif
#ifdef EDESTADDRREQ
case EDESTADDRREQ:
error = "Destination address required";
break;
#endif
#ifdef EAGAIN
case EAGAIN:
error = "No more processes";
break;
#endif
#ifdef ENOMEM
case ENOMEM:
error = "Not enough space";
break;
#endif
#ifdef EACCES
case EACCES:
error = "Permission denied";
break;
#endif
#ifdef EFAULT
case EFAULT:
error = "Bad address";
break;
#endif
#ifdef ENOTBLK
case ENOTBLK:
error = "Block device required";
break;
#endif
#ifdef EBUSY
case EBUSY:
error = "Device or resource busy";
break;
#endif
#ifdef EEXIST
case EEXIST:
error = "File exists";
break;
#endif
#ifdef EXDEV
case EXDEV:
error = "Cross-device link";
break;
#endif
#ifdef ENODEV
case ENODEV:
error = "No such device";
break;
#endif
#ifdef ENOTDIR
case ENOTDIR:
error = "Not a directory";
break;
#endif
#ifdef EHOSTDOWN
case EHOSTDOWN:
error = "Host is down";
break;
#endif
#ifdef EINPROGRESS
case EINPROGRESS:
error = "Connection already in progress";
break;
#endif
#ifdef EISDIR
case EISDIR:
error = "Is a directory";
break;
#endif
#ifdef EINVAL
case EINVAL:
error = "Invalid argument";
break;
#endif
#ifdef ENETDOWN
case ENETDOWN:
error = "Network interface is not configured";
break;
#endif
#ifdef ENFILE
case ENFILE:
error = "Too many open files in system";
break;
#endif
#ifdef EMFILE
case EMFILE:
error = "Too many open files";
break;
#endif
#ifdef ENOTTY
case ENOTTY:
error = "Not a character device";
break;
#endif
#ifdef ETXTBSY
case ETXTBSY:
error = "Text file busy";
break;
#endif
#ifdef EFBIG
case EFBIG:
error = "File too large";
break;
#endif
#ifdef EHOSTUNREACH
case EHOSTUNREACH:
error = "Host is unreachable";
break;
#endif
#ifdef ENOSPC
case ENOSPC:
error = "No space left on device";
break;
#endif
#ifdef ENOTSUP
case ENOTSUP:
error = "Not supported";
break;
#endif
#ifdef ESPIPE
case ESPIPE:
error = "Illegal seek";
break;
#endif
#ifdef EROFS
case EROFS:
error = "Read-only file system";
break;
#endif
#ifdef EMLINK
case EMLINK:
error = "Too many links";
break;
#endif
#ifdef EPIPE
case EPIPE:
error = "Broken pipe";
break;
#endif
#ifdef EDOM
case EDOM:
error = "Math argument";
break;
#endif
#ifdef ERANGE
case ERANGE:
error = "Result too large";
break;
#endif
#ifdef ENOMSG
case ENOMSG:
error = "No message of desired type";
break;
#endif
#ifdef EIDRM
case EIDRM:
error = "Identifier removed";
break;
#endif
#ifdef EDEADLK
case EDEADLK:
error = "Deadlock";
break;
#endif
#ifdef ENETUNREACH
case ENETUNREACH:
error = "Network is unreachable";
break;
#endif
#ifdef ENOLCK
case ENOLCK:
error = "No lock";
break;
#endif
#ifdef ENOSTR
case ENOSTR:
error = "Not a stream";
break;
#endif
#ifdef ETIME
case ETIME:
error = "Stream ioctl timeout";
break;
#endif
#ifdef ENOSR
case ENOSR:
error = "No stream resources";
break;
#endif
#ifdef ENONET
case ENONET:
error = "Machine is not on the network";
break;
#endif
#ifdef ENOPKG
case ENOPKG:
error = "No package";
break;
#endif
#ifdef EREMOTE
case EREMOTE:
error = "Resource is remote";
break;
#endif
#ifdef ENOLINK
case ENOLINK:
error = "Virtual circuit is gone";
break;
#endif
#ifdef EADV
case EADV:
error = "Advertise error";
break;
#endif
#ifdef ESRMNT
case ESRMNT:
error = "Srmount error";
break;
#endif
#ifdef ECOMM
case ECOMM:
error = "Communication error";
break;
#endif
#ifdef EPROTO
case EPROTO:
error = "Protocol error";
break;
#endif
#ifdef EPROTONOSUPPORT
case EPROTONOSUPPORT:
error = "Unknown protocol";
break;
#endif
#ifdef EMULTIHOP
case EMULTIHOP:
error = "Multihop attempted";
break;
#endif
#ifdef EBADMSG
case EBADMSG:
error = "Bad message";
break;
#endif
#ifdef ELIBACC
case ELIBACC:
error = "Cannot access a needed shared library";
break;
#endif
#ifdef ELIBBAD
case ELIBBAD:
error = "Accessing a corrupted shared library";
break;
#endif
#ifdef ELIBSCN
case ELIBSCN:
error = ".lib section in a.out corrupted";
break;
#endif
#ifdef ELIBMAX
case ELIBMAX:
error = "Attempting to link in more shared libraries than system limit";
break;
#endif
#ifdef ELIBEXEC
case ELIBEXEC:
error = "Cannot exec a shared library directly";
break;
#endif
#ifdef ENOSYS
case ENOSYS:
error = "Function not implemented";
break;
#endif
#ifdef ENMFILE
case ENMFILE:
error = "No more files";
break;
#endif
#ifdef ENOTEMPTY
case ENOTEMPTY:
error = "Directory not empty";
break;
#endif
#ifdef ENAMETOOLONG
case ENAMETOOLONG:
error = "File or path name too long";
break;
#endif
#ifdef ELOOP
case ELOOP:
error = "Too many symbolic links";
break;
#endif
#ifdef ENOBUFS
case ENOBUFS:
error = "No buffer space available";
break;
#endif
#ifdef EAFNOSUPPORT
case EAFNOSUPPORT:
error = "Address family not supported by protocol family";
break;
#endif
#ifdef EPROTOTYPE
case EPROTOTYPE:
error = "Protocol wrong type for socket";
break;
#endif
#ifdef ENOTSOCK
case ENOTSOCK:
error = "Socket operation on non-socket";
break;
#endif
#ifdef ENOPROTOOPT
case ENOPROTOOPT:
error = "Protocol not available";
break;
#endif
#ifdef ESHUTDOWN
case ESHUTDOWN:
error = "Can't send after socket shutdown";
break;
#endif
#ifdef ECONNREFUSED
case ECONNREFUSED:
error = "Connection refused";
break;
#endif
#ifdef EADDRINUSE
case EADDRINUSE:
error = "Address already in use";
break;
#endif
#ifdef ECONNABORTED
case ECONNABORTED:
error = "Software caused connection abort";
break;
#endif
#if (defined(EWOULDBLOCK) && (!defined (EAGAIN) || (EWOULDBLOCK != EAGAIN)))
case EWOULDBLOCK:
error = "Operation would block";
break;
#endif
#ifdef ENOTCONN
case ENOTCONN:
error = "Socket is not connected";
break;
#endif
#ifdef ESOCKTNOSUPPORT
case ESOCKTNOSUPPORT:
error = "Socket type not supported";
break;
#endif
#ifdef EISCONN
case EISCONN:
error = "Socket is already connected";
break;
#endif
#ifdef ECANCELED
case ECANCELED:
error = "Operation canceled";
break;
#endif
#ifdef ENOTRECOVERABLE
case ENOTRECOVERABLE:
error = "State not recoverable";
break;
#endif
#ifdef EOWNERDEAD
case EOWNERDEAD:
error = "Previous owner died";
break;
#endif
#ifdef ESTRPIPE
case ESTRPIPE:
error = "Streams pipe error";
break;
#endif
#if defined(EOPNOTSUPP) && (!defined(ENOTSUP) || (ENOTSUP != EOPNOTSUPP))
case EOPNOTSUPP:
error = "Operation not supported on socket";
break;
#endif
#ifdef EMSGSIZE
case EMSGSIZE:
error = "Message too long";
break;
#endif
#ifdef ETIMEDOUT
case ETIMEDOUT:
error = "Connection timed out";
break;
#endif
default:
if (!errptr)
errptr = &ptr->_errno;
if ((error = _user_strerror (errnum, internal, errptr)) == 0)
error = "";
break;
}
 
return error;
}
 
char *
_DEFUN(strerror, (int),
int errnum)
{
return _strerror_r (_REENT, errnum, 0, NULL);
}
/contrib/sdk/sources/newlib/libc/string/strlen.c
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)
{
_CONST char *start = str;
 
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
unsigned long *aligned_addr;
 
/* Align the pointer, so we can search a word at a time. */
while (UNALIGNED (str))
{
if (!*str)
return str - start;
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;
 
#endif /* not PREFER_SIZE_OVER_SPEED */
 
while (*str)
str++;
return str - start;
}
/contrib/sdk/sources/newlib/libc/string/strncasecmp.c
0,0 → 1,63
/*
FUNCTION
<<strncasecmp>>---case-insensitive character string compare
INDEX
strncasecmp
 
ANSI_SYNOPSIS
#include <strings.h>
int strncasecmp(const char *<[a]>, const char * <[b]>, size_t <[length]>);
 
TRAD_SYNOPSIS
#include <strings.h>
int strncasecmp(<[a]>, <[b]>, <[length]>)
char *<[a]>;
char *<[b]>;
size_t <[length]>
 
DESCRIPTION
<<strncasecmp>> compares up to <[length]> characters
from the string at <[a]> to the string at <[b]> in a
case-insensitive manner.
 
RETURNS
 
If <<*<[a]>>> sorts lexicographically after <<*<[b]>>> (after
both are converted to lowercase), <<strncasecmp>> returns a
number greater than zero. If the two strings are equivalent,
<<strncasecmp>> returns zero. If <<*<[a]>>> sorts
lexicographically before <<*<[b]>>>, <<strncasecmp>> returns a
number less than zero.
 
PORTABILITY
<<strncasecmp>> is in the Berkeley Software Distribution.
 
<<strncasecmp>> requires no supporting OS subroutines. It uses
tolower() from elsewhere in this library.
 
QUICKREF
strncasecmp
*/
 
#include <strings.h>
#include <ctype.h>
 
int
_DEFUN (strncasecmp, (s1, s2, n),
_CONST char *s1 _AND
_CONST char *s2 _AND
size_t n)
{
_CONST unsigned char *ucs1 = (_CONST unsigned char *) s1;
_CONST unsigned char *ucs2 = (_CONST unsigned char *) s2;
int d = 0;
for ( ; n != 0; n--)
{
_CONST int c1 = tolower(*ucs1++);
_CONST int c2 = tolower(*ucs2++);
if (((d = c1 - c2) != 0) || (c2 == '\0'))
break;
}
return d;
}
/contrib/sdk/sources/newlib/libc/string/strncat.c
0,0 → 1,114
/*
FUNCTION
<<strncat>>---concatenate strings
 
INDEX
strncat
 
ANSI_SYNOPSIS
#include <string.h>
char *strncat(char *<[dst]>, const char *<[src]>, size_t <[length]>);
 
TRAD_SYNOPSIS
#include <string.h>
char *strncat(<[dst]>, <[src]>, <[length]>)
char *<[dst]>;
char *<[src]>;
size_t <[length]>;
 
DESCRIPTION
<<strncat>> appends not more than <[length]> characters from
the string pointed to by <[src]> (including the terminating
null character) to the end of the string pointed to by
<[dst]>. The initial character of <[src]> overwrites the null
character at the end of <[dst]>. A terminating null character
is always appended to the result
 
WARNINGS
Note that a null is always appended, so that if the copy is
limited by the <[length]> argument, the number of characters
appended to <[dst]> is <<n + 1>>.
 
RETURNS
This function returns the initial value of <[dst]>
 
PORTABILITY
<<strncat>> is ANSI C.
 
<<strncat>> requires no supporting OS subroutines.
 
QUICKREF
strncat ansi pure
*/
 
#include <string.h>
#include <limits.h>
 
/* Nonzero if X is aligned on a "long" boundary. */
#define ALIGNED(X) \
(((long)X & (sizeof (long) - 1)) == 0)
 
#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 (strncat, (s1, s2, n),
char *s1 _AND
_CONST char *s2 _AND
size_t n)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *s = s1;
 
while (*s1)
s1++;
while (n-- != 0 && (*s1++ = *s2++))
{
if (n == 0)
*s1 = '\0';
}
 
return s;
#else
char *s = s1;
 
/* Skip over the data in s1 as quickly as possible. */
if (ALIGNED (s1))
{
unsigned long *aligned_s1 = (unsigned long *)s1;
while (!DETECTNULL (*aligned_s1))
aligned_s1++;
 
s1 = (char *)aligned_s1;
}
 
while (*s1)
s1++;
 
/* s1 now points to the its trailing null character, now copy
up to N bytes from S2 into S1 stopping if a NULL is encountered
in S2.
 
It is not safe to use strncpy here since it copies EXACTLY N
characters, NULL padding if necessary. */
while (n-- != 0 && (*s1++ = *s2++))
{
if (n == 0)
*s1 = '\0';
}
return s;
#endif /* not PREFER_SIZE_OVER_SPEED */
}
/contrib/sdk/sources/newlib/libc/string/strncmp.c
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 */
}
/contrib/sdk/sources/newlib/libc/string/strncpy.c
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 */
}
/contrib/sdk/sources/newlib/libc/string/strndup.c
0,0 → 1,16
#ifndef _REENT_ONLY
 
#include <_ansi.h>
#include <reent.h>
#include <stdlib.h>
#include <string.h>
 
char *
_DEFUN (strndup, (str, n),
_CONST char *str _AND
size_t n)
{
return _strndup_r (_REENT, str, n);
}
 
#endif /* !_REENT_ONLY */
/contrib/sdk/sources/newlib/libc/string/strndup_r.c
0,0 → 1,27
#include <reent.h>
#include <stdlib.h>
#include <string.h>
 
char *
_DEFUN (_strndup_r, (reent_ptr, str, n),
struct _reent *reent_ptr _AND
_CONST char *str _AND
size_t n)
{
_CONST char *ptr = str;
size_t len;
char *copy;
 
while (n-- > 0 && *ptr)
ptr++;
 
len = ptr - str;
 
copy = _malloc_r (reent_ptr, len + 1);
if (copy)
{
memcpy (copy, str, len);
copy[len] = '\0';
}
return copy;
}
/contrib/sdk/sources/newlib/libc/string/strnlen.c
0,0 → 1,49
/*
FUNCTION
<<strnlen>>---character string length
INDEX
strnlen
 
ANSI_SYNOPSIS
#include <string.h>
size_t strnlen(const char *<[str]>, size_t <[n]>);
 
TRAD_SYNOPSIS
#include <string.h>
size_t strnlen(<[str]>, <[n]>)
char *<[src]>;
size_t <[n]>;
 
DESCRIPTION
The <<strnlen>> function works out the length of the string
starting at <<*<[str]>>> by counting chararacters until it
reaches a NUL character or the maximum: <[n]> number of
characters have been inspected.
 
RETURNS
<<strnlen>> returns the character count or <[n]>.
 
PORTABILITY
<<strnlen>> is a GNU extension.
 
<<strnlen>> requires no supporting OS subroutines.
 
*/
 
#undef __STRICT_ANSI__
#include <_ansi.h>
#include <string.h>
 
size_t
_DEFUN (strnlen, (str, n),
_CONST char *str _AND
size_t n)
{
_CONST char *start = str;
 
while (n-- > 0 && *str)
str++;
 
return str - start;
}
/contrib/sdk/sources/newlib/libc/string/strpbrk.c
0,0 → 1,58
/*
FUNCTION
<<strpbrk>>---find characters in string
 
INDEX
strpbrk
 
ANSI_SYNOPSIS
#include <string.h>
char *strpbrk(const char *<[s1]>, const char *<[s2]>);
 
TRAD_SYNOPSIS
#include <string.h>
char *strpbrk(<[s1]>, <[s2]>)
char *<[s1]>;
char *<[s2]>;
 
DESCRIPTION
This function locates the first occurence in the string
pointed to by <[s1]> of any character in string pointed to by
<[s2]> (excluding the terminating null character).
 
RETURNS
<<strpbrk>> returns a pointer to the character found in <[s1]>, or a
null pointer if no character from <[s2]> occurs in <[s1]>.
 
PORTABILITY
<<strpbrk>> requires no supporting OS subroutines.
*/
 
#include <string.h>
 
char *
_DEFUN (strpbrk, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
_CONST char *c = s2;
if (!*s1)
return (char *) NULL;
 
while (*s1)
{
for (c = s2; *c; c++)
{
if (*s1 == *c)
break;
}
if (*c)
break;
s1++;
}
 
if (*c == '\0')
s1 = NULL;
 
return (char *) s1;
}
/contrib/sdk/sources/newlib/libc/string/strrchr.c
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;
}
/contrib/sdk/sources/newlib/libc/string/strsep.c
0,0 → 1,19
/* BSD strsep function */
 
/* Copyright 2002, Red Hat Inc. */
 
/* undef STRICT_ANSI so that strsep prototype will be defined */
#undef __STRICT_ANSI__
#include <string.h>
#include <_ansi.h>
#include <reent.h>
 
extern char *__strtok_r (char *, const char *, char **, int);
 
char *
_DEFUN (strsep, (source_ptr, delim),
register char **source_ptr _AND
register const char *delim)
{
return __strtok_r (*source_ptr, delim, source_ptr, 0);
}
/contrib/sdk/sources/newlib/libc/string/strspn.c
0,0 → 1,59
/*
FUNCTION
<<strspn>>---find initial match
 
INDEX
strspn
 
ANSI_SYNOPSIS
#include <string.h>
size_t strspn(const char *<[s1]>, const char *<[s2]>);
 
TRAD_SYNOPSIS
#include <string.h>
size_t strspn(<[s1]>, <[s2]>)
char *<[s1]>;
char *<[s2]>;
 
DESCRIPTION
This function computes the length of the initial segment of
the string pointed to by <[s1]> which consists entirely of
characters from the string pointed to by <[s2]> (excluding the
terminating null character).
 
RETURNS
<<strspn>> returns the length of the segment found.
 
PORTABILITY
<<strspn>> is ANSI C.
 
<<strspn>> requires no supporting OS subroutines.
 
QUICKREF
strspn ansi pure
*/
 
#include <string.h>
 
size_t
_DEFUN (strspn, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
_CONST char *s = s1;
_CONST char *c;
 
while (*s1)
{
for (c = s2; *c; c++)
{
if (*s1 == *c)
break;
}
if (*c == '\0')
break;
s1++;
}
 
return s1 - s;
}
/contrib/sdk/sources/newlib/libc/string/strstr.c
0,0 → 1,121
/*
FUNCTION
<<strstr>>---find string segment
 
INDEX
strstr
 
ANSI_SYNOPSIS
#include <string.h>
char *strstr(const char *<[s1]>, const char *<[s2]>);
 
TRAD_SYNOPSIS
#include <string.h>
char *strstr(<[s1]>, <[s2]>)
char *<[s1]>;
char *<[s2]>;
 
DESCRIPTION
Locates the first occurrence in the string pointed to by <[s1]> of
the sequence of characters in the string pointed to by <[s2]>
(excluding the terminating null character).
 
RETURNS
Returns a pointer to the located string segment, or a null
pointer if the string <[s2]> is not found. If <[s2]> points to
a string with zero length, <[s1]> is returned.
 
PORTABILITY
<<strstr>> is ANSI C.
 
<<strstr>> requires no supporting OS subroutines.
 
QUICKREF
strstr ansi pure
*/
 
#include <string.h>
 
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
# define RETURN_TYPE char *
# define AVAILABLE(h, h_l, j, n_l) \
(!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \
&& ((h_l) = (j) + (n_l)))
# include "str-two-way.h"
#endif
 
char *
_DEFUN (strstr, (searchee, lookfor),
_CONST char *searchee _AND
_CONST char *lookfor)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
 
/* Less code size, but quadratic performance in the worst case. */
if (*searchee == 0)
{
if (*lookfor)
return (char *) NULL;
return (char *) searchee;
}
 
while (*searchee)
{
size_t i;
i = 0;
 
while (1)
{
if (lookfor[i] == 0)
{
return (char *) searchee;
}
 
if (lookfor[i] != searchee[i])
{
break;
}
i++;
}
searchee++;
}
 
return (char *) NULL;
 
#else /* compilation for speed */
 
/* Larger code size, but guaranteed linear performance. */
const char *haystack = searchee;
const char *needle = lookfor;
size_t needle_len; /* Length of NEEDLE. */
size_t haystack_len; /* Known minimum length of HAYSTACK. */
int ok = 1; /* True if NEEDLE is prefix of HAYSTACK. */
 
/* Determine length of NEEDLE, and in the process, make sure
HAYSTACK is at least as long (no point processing all of a long
NEEDLE if HAYSTACK is too short). */
while (*haystack && *needle)
ok &= *haystack++ == *needle++;
if (*needle)
return NULL;
if (ok)
return (char *) searchee;
 
/* Reduce the size of haystack using strchr, since it has a smaller
linear coefficient than the Two-Way algorithm. */
needle_len = needle - lookfor;
haystack = strchr (searchee + 1, *lookfor);
if (!haystack || needle_len == 1)
return (char *) haystack;
haystack_len = (haystack > searchee + needle_len ? 1
: needle_len + searchee - haystack);
 
/* Perform the search. */
if (needle_len < LONG_NEEDLE_THRESHOLD)
return two_way_short_needle ((const unsigned char *) haystack,
haystack_len,
(const unsigned char *) lookfor, needle_len);
return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
(const unsigned char *) lookfor, needle_len);
#endif /* compilation for speed */
}
/contrib/sdk/sources/newlib/libc/string/strtok.c
0,0 → 1,101
/*
FUNCTION
<<strtok>>, <<strtok_r>>, <<strsep>>---get next token from a string
 
INDEX
strtok
 
INDEX
strtok_r
 
INDEX
strsep
 
ANSI_SYNOPSIS
#include <string.h>
char *strtok(char *<[source]>, const char *<[delimiters]>)
char *strtok_r(char *<[source]>, const char *<[delimiters]>,
char **<[lasts]>)
char *strsep(char **<[source_ptr]>, const char *<[delimiters]>)
 
TRAD_SYNOPSIS
#include <string.h>
char *strtok(<[source]>, <[delimiters]>)
char *<[source]>;
char *<[delimiters]>;
 
char *strtok_r(<[source]>, <[delimiters]>, <[lasts]>)
char *<[source]>;
char *<[delimiters]>;
char **<[lasts]>;
 
char *strsep(<[source_ptr]>, <[delimiters]>)
char **<[source_ptr]>;
char *<[delimiters]>;
 
DESCRIPTION
The <<strtok>> function is used to isolate sequential tokens in a
null-terminated string, <<*<[source]>>>. These tokens are delimited
in the string by at least one of the characters in <<*<[delimiters]>>>.
The first time that <<strtok>> is called, <<*<[source]>>> should be
specified; subsequent calls, wishing to obtain further tokens from
the same string, should pass a null pointer instead. The separator
string, <<*<[delimiters]>>>, must be supplied each time and may
change between calls.
 
The <<strtok>> function returns a pointer to the beginning of each
subsequent token in the string, after replacing the separator
character itself with a null character. When no more tokens remain,
a null pointer is returned.
 
The <<strtok_r>> function has the same behavior as <<strtok>>, except
a pointer to placeholder <<*<[lasts]>>> must be supplied by the caller.
 
The <<strsep>> function is similar in behavior to <<strtok>>, except
a pointer to the string pointer must be supplied <<<[source_ptr]>>> and
the function does not skip leading delimiters. When the string starts
with a delimiter, the delimiter is changed to the null character and
the empty string is returned. Like <<strtok_r>> and <<strtok>>, the
<<*<[source_ptr]>>> is updated to the next character following the
last delimiter found or NULL if the end of string is reached with
no more delimiters.
 
RETURNS
<<strtok>>, <<strtok_r>>, and <<strsep>> all return a pointer to the
next token, or <<NULL>> if no more tokens can be found. For
<<strsep>>, a token may be the empty string.
 
NOTES
<<strtok>> is unsafe for multi-threaded applications. <<strtok_r>>
and <<strsep>> are thread-safe and should be used instead.
 
PORTABILITY
<<strtok>> is ANSI C.
<<strtok_r>> is POSIX.
<<strsep>> is a BSD extension.
 
<<strtok>>, <<strtok_r>>, and <<strsep>> require no supporting OS subroutines.
 
QUICKREF
strtok ansi impure
*/
 
/* undef STRICT_ANSI so that strtok_r prototype will be defined */
#undef __STRICT_ANSI__
#include <string.h>
#include <_ansi.h>
#include <reent.h>
 
#ifndef _REENT_ONLY
 
extern char *__strtok_r (char *, const char *, char **, int);
 
char *
_DEFUN (strtok, (s, delim),
register char *s _AND
register const char *delim)
{
_REENT_CHECK_MISC(_REENT);
return __strtok_r (s, delim, &(_REENT_STRTOK_LAST(_REENT)), 1);
}
#endif
/contrib/sdk/sources/newlib/libc/string/strtok_r.c
0,0 → 1,99
/*
* Copyright (c) 1988 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. 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 <string.h>
 
char *
_DEFUN (__strtok_r, (s, delim, lasts, skip_leading_delim),
register char *s _AND
register const char *delim _AND
char **lasts _AND
int skip_leading_delim)
{
register char *spanp;
register int c, sc;
char *tok;
 
 
if (s == NULL && (s = *lasts) == NULL)
return (NULL);
 
/*
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
*/
cont:
c = *s++;
for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
if (c == sc) {
if (skip_leading_delim) {
goto cont;
}
else {
*lasts = s;
s[-1] = 0;
return (s - 1);
}
}
}
 
if (c == 0) { /* no non-delimiter characters */
*lasts = NULL;
return (NULL);
}
tok = s - 1;
 
/*
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
* Note that delim must have one NUL; we stop if we see that, too.
*/
for (;;) {
c = *s++;
spanp = (char *)delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*lasts = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
 
char *
_DEFUN (strtok_r, (s, delim, lasts),
register char *s _AND
register const char *delim _AND
char **lasts)
{
return __strtok_r (s, delim, lasts, 1);
}
/contrib/sdk/sources/newlib/libc/string/strupr.c
0,0 → 1,46
/*
FUNCTION
<<strupr>>---force string to uppercase
INDEX
strupr
 
ANSI_SYNOPSIS
#include <string.h>
char *strupr(char *<[a]>);
 
TRAD_SYNOPSIS
#include <string.h>
char *strupr(<[a]>)
char *<[a]>;
 
DESCRIPTION
<<strupr>> converts each character in the string at <[a]> to
uppercase.
 
RETURNS
<<strupr>> returns its argument, <[a]>.
 
PORTABILITY
<<strupr>> is not widely portable.
 
<<strupr>> requires no supporting OS subroutines.
 
QUICKREF
strupr
*/
 
#include <string.h>
#include <ctype.h>
 
char *
_DEFUN (strupr, (s),
char *s)
{
unsigned char *ucs = (unsigned char *) s;
for ( ; *ucs != '\0'; ucs++)
{
*ucs = toupper(*ucs);
}
return s;
}
/contrib/sdk/sources/newlib/libc/string/u_strerr.c
0,0 → 1,10
#include <_ansi.h>
 
char *
_DEFUN(_user_strerror, (errnum, internal, errptr),
int errnum _AND
int internal _AND
int *errptr)
{
return 0;
}
/contrib/sdk/sources/newlib/libc/string/vsprintf.c
0,0 → 1,1379
/*
* linux/lib/vsprintf.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
 
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
/*
* Wirzenius wrote this portably, Torvalds fucked it up :-)
*/
 
/*
* Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
* - changed to provide snprintf and vsnprintf functions
* So Feb 1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de>
* - scnprintf and vscnprintf
*/
 
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
 
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdint.h>
 
//#include <linux/module.h>
//#include <types.h>
//#include <linux/kernel.h>
//#include <linux/kallsyms.h>
//#include <linux/uaccess.h>
//#include <linux/ioport.h>
 
//#include <asm/page.h> /* for PAGE_SIZE */
//#include <asm/div64.h>
//#include <asm/sections.h> /* for dereference_function_descriptor() */
 
#define do_div(n, base) \
({ \
unsigned long __upper, __low, __high, __mod, __base; \
__base = (base); \
asm("":"=a" (__low), "=d" (__high) : "A" (n)); \
__upper = __high; \
if (__high) { \
__upper = __high % (__base); \
__high = __high / (__base); \
} \
asm("divl %2":"=a" (__low), "=d" (__mod) \
: "rm" (__base), "0" (__low), "1" (__upper)); \
asm("":"=A" (n) : "a" (__low), "d" (__high)); \
__mod; \
})
 
#define EPERM 1 /* Operation not permitted */
#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 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource 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 /* File table overflow */
#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 argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
 
#define PAGE_SIZE 4096
 
/* Works only for digits and letters, but small and fast */
#define TOLOWER(x) ((x) | 0x20)
 
static unsigned int simple_guess_base(const char *cp)
{
if (cp[0] == '0') {
if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
return 16;
else
return 8;
} else {
return 10;
}
}
 
/**
* simple_strtoul - convert a string to an unsigned long
* @cp: The start of the string
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
{
unsigned long result = 0;
 
if (!base)
base = simple_guess_base(cp);
 
if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
cp += 2;
 
while (isxdigit(*cp)) {
unsigned int value;
 
value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
if (value >= base)
break;
result = result * base + value;
cp++;
}
 
if (endp)
*endp = (char *)cp;
return result;
}
 
/**
* simple_strtol - convert a string to a signed long
* @cp: The start of the string
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
long simple_strtol(const char *cp, char **endp, unsigned int base)
{
if(*cp == '-')
return -simple_strtoul(cp + 1, endp, base);
return simple_strtoul(cp, endp, base);
}
 
/**
* simple_strtoull - convert a string to an unsigned long long
* @cp: The start of the string
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
{
unsigned long long result = 0;
 
if (!base)
base = simple_guess_base(cp);
 
if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
cp += 2;
 
while (isxdigit(*cp)) {
unsigned int value;
 
value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
if (value >= base)
break;
result = result * base + value;
cp++;
}
 
if (endp)
*endp = (char *)cp;
return result;
}
 
/**
* simple_strtoll - convert a string to a signed long long
* @cp: The start of the string
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
long long simple_strtoll(const char *cp, char **endp, unsigned int base)
{
if(*cp=='-')
return -simple_strtoull(cp + 1, endp, base);
return simple_strtoull(cp, endp, base);
}
 
/**
* strict_strtoul - convert a string to an unsigned long strictly
* @cp: The string to be converted
* @base: The number base to use
* @res: The converted result value
*
* strict_strtoul converts a string to an unsigned long only if the
* string is really an unsigned long string, any string containing
* any invalid char at the tail will be rejected and -EINVAL is returned,
* only a newline char at the tail is acceptible because people generally
* change a module parameter in the following way:
*
* echo 1024 > /sys/module/e1000/parameters/copybreak
*
* echo will append a newline to the tail.
*
* It returns 0 if conversion is successful and *res is set to the converted
* value, otherwise it returns -EINVAL and *res is set to 0.
*
* simple_strtoul just ignores the successive invalid characters and
* return the converted value of prefix part of the string.
*/
int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
{
char *tail;
unsigned long val;
size_t len;
 
*res = 0;
len = strlen(cp);
if (len == 0)
return -EINVAL;
 
val = simple_strtoul(cp, &tail, base);
if (tail == cp)
return -EINVAL;
if ((*tail == '\0') ||
((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
*res = val;
return 0;
}
 
return -EINVAL;
}
 
/**
* strict_strtol - convert a string to a long strictly
* @cp: The string to be converted
* @base: The number base to use
* @res: The converted result value
*
* strict_strtol is similiar to strict_strtoul, but it allows the first
* character of a string is '-'.
*
* It returns 0 if conversion is successful and *res is set to the converted
* value, otherwise it returns -EINVAL and *res is set to 0.
*/
int strict_strtol(const char *cp, unsigned int base, long *res)
{
int ret;
if (*cp == '-') {
ret = strict_strtoul(cp + 1, base, (unsigned long *)res);
if (!ret)
*res = -(*res);
} else {
ret = strict_strtoul(cp, base, (unsigned long *)res);
}
 
return ret;
}
 
/**
* strict_strtoull - convert a string to an unsigned long long strictly
* @cp: The string to be converted
* @base: The number base to use
* @res: The converted result value
*
* strict_strtoull converts a string to an unsigned long long only if the
* string is really an unsigned long long string, any string containing
* any invalid char at the tail will be rejected and -EINVAL is returned,
* only a newline char at the tail is acceptible because people generally
* change a module parameter in the following way:
*
* echo 1024 > /sys/module/e1000/parameters/copybreak
*
* echo will append a newline to the tail of the string.
*
* It returns 0 if conversion is successful and *res is set to the converted
* value, otherwise it returns -EINVAL and *res is set to 0.
*
* simple_strtoull just ignores the successive invalid characters and
* return the converted value of prefix part of the string.
*/
int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res)
{
char *tail;
unsigned long long val;
size_t len;
 
*res = 0;
len = strlen(cp);
if (len == 0)
return -EINVAL;
 
val = simple_strtoull(cp, &tail, base);
if (tail == cp)
return -EINVAL;
if ((*tail == '\0') ||
((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
*res = val;
return 0;
}
 
return -EINVAL;
}
 
/**
* strict_strtoll - convert a string to a long long strictly
* @cp: The string to be converted
* @base: The number base to use
* @res: The converted result value
*
* strict_strtoll is similiar to strict_strtoull, but it allows the first
* character of a string is '-'.
*
* It returns 0 if conversion is successful and *res is set to the converted
* value, otherwise it returns -EINVAL and *res is set to 0.
*/
int strict_strtoll(const char *cp, unsigned int base, long long *res)
{
int ret;
if (*cp == '-') {
ret = strict_strtoull(cp + 1, base, (unsigned long long *)res);
if (!ret)
*res = -(*res);
} else {
ret = strict_strtoull(cp, base, (unsigned long long *)res);
}
 
return ret;
}
 
static int skip_atoi(const char **s)
{
int i=0;
 
while (isdigit(**s))
i = i*10 + *((*s)++) - '0';
return i;
}
 
/* Decimal conversion is by far the most typical, and is used
* for /proc and /sys data. This directly impacts e.g. top performance
* with many processes running. We optimize it for speed
* using code from
* http://www.cs.uiowa.edu/~jones/bcd/decimal.html
* (with permission from the author, Douglas W. Jones). */
 
/* Formats correctly any integer in [0,99999].
* Outputs from one to five digits depending on input.
* On i386 gcc 4.1.2 -O2: ~250 bytes of code. */
static char* put_dec_trunc(char *buf, unsigned q)
{
unsigned d3, d2, d1, d0;
d1 = (q>>4) & 0xf;
d2 = (q>>8) & 0xf;
d3 = (q>>12);
 
d0 = 6*(d3 + d2 + d1) + (q & 0xf);
q = (d0 * 0xcd) >> 11;
d0 = d0 - 10*q;
*buf++ = d0 + '0'; /* least significant digit */
d1 = q + 9*d3 + 5*d2 + d1;
if (d1 != 0) {
q = (d1 * 0xcd) >> 11;
d1 = d1 - 10*q;
*buf++ = d1 + '0'; /* next digit */
 
d2 = q + 2*d2;
if ((d2 != 0) || (d3 != 0)) {
q = (d2 * 0xd) >> 7;
d2 = d2 - 10*q;
*buf++ = d2 + '0'; /* next digit */
 
d3 = q + 4*d3;
if (d3 != 0) {
q = (d3 * 0xcd) >> 11;
d3 = d3 - 10*q;
*buf++ = d3 + '0'; /* next digit */
if (q != 0)
*buf++ = q + '0'; /* most sign. digit */
}
}
}
return buf;
}
/* Same with if's removed. Always emits five digits */
static char* put_dec_full(char *buf, unsigned q)
{
/* BTW, if q is in [0,9999], 8-bit ints will be enough, */
/* but anyway, gcc produces better code with full-sized ints */
unsigned d3, d2, d1, d0;
d1 = (q>>4) & 0xf;
d2 = (q>>8) & 0xf;
d3 = (q>>12);
 
/* Possible ways to approx. divide by 10 */
/* gcc -O2 replaces multiply with shifts and adds */
// (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386)
// (x * 0x67) >> 10: 1100111
// (x * 0x34) >> 9: 110100 - same
// (x * 0x1a) >> 8: 11010 - same
// (x * 0x0d) >> 7: 1101 - same, shortest code (on i386)
 
d0 = 6*(d3 + d2 + d1) + (q & 0xf);
q = (d0 * 0xcd) >> 11;
d0 = d0 - 10*q;
*buf++ = d0 + '0';
d1 = q + 9*d3 + 5*d2 + d1;
q = (d1 * 0xcd) >> 11;
d1 = d1 - 10*q;
*buf++ = d1 + '0';
 
d2 = q + 2*d2;
q = (d2 * 0xd) >> 7;
d2 = d2 - 10*q;
*buf++ = d2 + '0';
 
d3 = q + 4*d3;
q = (d3 * 0xcd) >> 11; /* - shorter code */
/* q = (d3 * 0x67) >> 10; - would also work */
d3 = d3 - 10*q;
*buf++ = d3 + '0';
*buf++ = q + '0';
return buf;
}
/* No inlining helps gcc to use registers better */
static char* put_dec(char *buf, unsigned long long num)
{
while (1) {
unsigned rem;
if (num < 100000)
return put_dec_trunc(buf, num);
rem = do_div(num, 100000);
buf = put_dec_full(buf, rem);
}
}
 
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
#define SMALL 32 /* Must be 32 == 0x20 */
#define SPECIAL 64 /* 0x */
 
enum format_type {
FORMAT_TYPE_NONE, /* Just a string part */
FORMAT_TYPE_WIDTH,
FORMAT_TYPE_PRECISION,
FORMAT_TYPE_CHAR,
FORMAT_TYPE_STR,
FORMAT_TYPE_PTR,
FORMAT_TYPE_PERCENT_CHAR,
FORMAT_TYPE_INVALID,
FORMAT_TYPE_LONG_LONG,
FORMAT_TYPE_ULONG,
FORMAT_TYPE_LONG,
FORMAT_TYPE_UBYTE,
FORMAT_TYPE_BYTE,
FORMAT_TYPE_USHORT,
FORMAT_TYPE_SHORT,
FORMAT_TYPE_UINT,
FORMAT_TYPE_INT,
FORMAT_TYPE_NRCHARS,
FORMAT_TYPE_SIZE_T,
FORMAT_TYPE_PTRDIFF
};
 
struct printf_spec {
enum format_type type;
int flags; /* flags to number() */
int field_width; /* width of output field */
int base;
int precision; /* # of digits/chars */
int qualifier;
};
 
static char *number(char *buf, char *end, unsigned long long num,
struct printf_spec spec)
{
/* we are called with base 8, 10 or 16, only, thus don't need "G..." */
static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
 
char tmp[66];
char sign;
char locase;
int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10);
int i;
 
/* locase = 0 or 0x20. ORing digits or letters with 'locase'
* produces same digits or (maybe lowercased) letters */
locase = (spec.flags & SMALL);
if (spec.flags & LEFT)
spec.flags &= ~ZEROPAD;
sign = 0;
if (spec.flags & SIGN) {
if ((signed long long) num < 0) {
sign = '-';
num = - (signed long long) num;
spec.field_width--;
} else if (spec.flags & PLUS) {
sign = '+';
spec.field_width--;
} else if (spec.flags & SPACE) {
sign = ' ';
spec.field_width--;
}
}
if (need_pfx) {
spec.field_width--;
if (spec.base == 16)
spec.field_width--;
}
 
/* generate full string in tmp[], in reverse order */
i = 0;
if (num == 0)
tmp[i++] = '0';
/* Generic code, for any base:
else do {
tmp[i++] = (digits[do_div(num,base)] | locase);
} while (num != 0);
*/
else if (spec.base != 10) { /* 8 or 16 */
int mask = spec.base - 1;
int shift = 3;
if (spec.base == 16) shift = 4;
do {
tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
num >>= shift;
} while (num);
} else { /* base 10 */
i = put_dec(tmp, num) - tmp;
}
 
/* printing 100 using %2d gives "100", not "00" */
if (i > spec.precision)
spec.precision = i;
/* leading space padding */
spec.field_width -= spec.precision;
if (!(spec.flags & (ZEROPAD+LEFT))) {
while(--spec.field_width >= 0) {
if (buf < end)
*buf = ' ';
++buf;
}
}
/* sign */
if (sign) {
if (buf < end)
*buf = sign;
++buf;
}
/* "0x" / "0" prefix */
if (need_pfx) {
if (buf < end)
*buf = '0';
++buf;
if (spec.base == 16) {
if (buf < end)
*buf = ('X' | locase);
++buf;
}
}
/* zero or space padding */
if (!(spec.flags & LEFT)) {
char c = (spec.flags & ZEROPAD) ? '0' : ' ';
while (--spec.field_width >= 0) {
if (buf < end)
*buf = c;
++buf;
}
}
/* hmm even more zero padding? */
while (i <= --spec.precision) {
if (buf < end)
*buf = '0';
++buf;
}
/* actual digits of result */
while (--i >= 0) {
if (buf < end)
*buf = tmp[i];
++buf;
}
/* trailing space padding */
while (--spec.field_width >= 0) {
if (buf < end)
*buf = ' ';
++buf;
}
return buf;
}
 
static char *string(char *buf, char *end, char *s, struct printf_spec spec)
{
int len, i;
 
if ((unsigned long)s < PAGE_SIZE)
s = "<NULL>";
 
len = strnlen(s, spec.precision);
 
if (!(spec.flags & LEFT)) {
while (len < spec.field_width--) {
if (buf < end)
*buf = ' ';
++buf;
}
}
for (i = 0; i < len; ++i) {
if (buf < end)
*buf = *s;
++buf; ++s;
}
while (len < spec.field_width--) {
if (buf < end)
*buf = ' ';
++buf;
}
return buf;
}
 
 
/*
* Show a '%p' thing.
*/
static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
struct printf_spec spec)
{
if (!ptr)
return string(buf, end, "(null)", spec);
 
spec.flags |= SMALL;
if (spec.field_width == -1) {
spec.field_width = 2*sizeof(void *);
spec.flags |= ZEROPAD;
}
spec.base = 16;
 
return number(buf, end, (unsigned long) ptr, spec);
}
 
/*
* Helper function to decode printf style format.
* Each call decode a token from the format and return the
* number of characters read (or likely the delta where it wants
* to go on the next call).
* The decoded token is returned through the parameters
*
* 'h', 'l', or 'L' for integer fields
* 'z' support added 23/7/1999 S.H.
* 'z' changed to 'Z' --davidm 1/25/99
* 't' added for ptrdiff_t
*
* @fmt: the format string
* @type of the token returned
* @flags: various flags such as +, -, # tokens..
* @field_width: overwritten width
* @base: base of the number (octal, hex, ...)
* @precision: precision of a number
* @qualifier: qualifier of a number (long, size_t, ...)
*/
static int format_decode(const char *fmt, struct printf_spec *spec)
{
const char *start = fmt;
 
/* we finished early by reading the field width */
if (spec->type == FORMAT_TYPE_WIDTH) {
if (spec->field_width < 0) {
spec->field_width = -spec->field_width;
spec->flags |= LEFT;
}
spec->type = FORMAT_TYPE_NONE;
goto precision;
}
 
/* we finished early by reading the precision */
if (spec->type == FORMAT_TYPE_PRECISION) {
if (spec->precision < 0)
spec->precision = 0;
 
spec->type = FORMAT_TYPE_NONE;
goto qualifier;
}
 
/* By default */
spec->type = FORMAT_TYPE_NONE;
 
for (; *fmt ; ++fmt) {
if (*fmt == '%')
break;
}
 
/* Return the current non-format string */
if (fmt != start || !*fmt)
return fmt - start;
 
/* Process flags */
spec->flags = 0;
 
while (1) { /* this also skips first '%' */
int found = 1;
 
++fmt;
 
switch (*fmt) {
case '-': spec->flags |= LEFT; break;
case '+': spec->flags |= PLUS; break;
case ' ': spec->flags |= SPACE; break;
case '#': spec->flags |= SPECIAL; break;
case '0': spec->flags |= ZEROPAD; break;
default: found = 0;
}
 
if (!found)
break;
}
 
/* get field width */
spec->field_width = -1;
 
if (isdigit(*fmt))
spec->field_width = skip_atoi(&fmt);
else if (*fmt == '*') {
/* it's the next argument */
spec->type = FORMAT_TYPE_WIDTH;
return ++fmt - start;
}
 
precision:
/* get the precision */
spec->precision = -1;
if (*fmt == '.') {
++fmt;
if (isdigit(*fmt)) {
spec->precision = skip_atoi(&fmt);
if (spec->precision < 0)
spec->precision = 0;
} else if (*fmt == '*') {
/* it's the next argument */
spec->type = FORMAT_TYPE_PRECISION;
return ++fmt - start;
}
}
 
qualifier:
/* get the conversion qualifier */
spec->qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
*fmt == 'Z' || *fmt == 'z' || *fmt == 't') {
spec->qualifier = *fmt++;
if (unlikely(spec->qualifier == *fmt)) {
if (spec->qualifier == 'l') {
spec->qualifier = 'L';
++fmt;
} else if (spec->qualifier == 'h') {
spec->qualifier = 'H';
++fmt;
}
}
}
 
/* default base */
spec->base = 10;
switch (*fmt) {
case 'c':
spec->type = FORMAT_TYPE_CHAR;
return ++fmt - start;
 
case 's':
spec->type = FORMAT_TYPE_STR;
return ++fmt - start;
 
case 'p':
spec->type = FORMAT_TYPE_PTR;
return fmt - start;
/* skip alnum */
 
case 'n':
spec->type = FORMAT_TYPE_NRCHARS;
return ++fmt - start;
 
case '%':
spec->type = FORMAT_TYPE_PERCENT_CHAR;
return ++fmt - start;
 
/* integer number formats - set up the flags and "break" */
case 'o':
spec->base = 8;
break;
 
case 'x':
spec->flags |= SMALL;
 
case 'X':
spec->base = 16;
break;
 
case 'd':
case 'i':
spec->flags |= SIGN;
case 'u':
break;
 
default:
spec->type = FORMAT_TYPE_INVALID;
return fmt - start;
}
 
if (spec->qualifier == 'L')
spec->type = FORMAT_TYPE_LONG_LONG;
else if (spec->qualifier == 'l') {
if (spec->flags & SIGN)
spec->type = FORMAT_TYPE_LONG;
else
spec->type = FORMAT_TYPE_ULONG;
} else if (spec->qualifier == 'Z' || spec->qualifier == 'z') {
spec->type = FORMAT_TYPE_SIZE_T;
} else if (spec->qualifier == 't') {
spec->type = FORMAT_TYPE_PTRDIFF;
} else if (spec->qualifier == 'H') {
if (spec->flags & SIGN)
spec->type = FORMAT_TYPE_BYTE;
else
spec->type = FORMAT_TYPE_UBYTE;
} else if (spec->qualifier == 'h') {
if (spec->flags & SIGN)
spec->type = FORMAT_TYPE_SHORT;
else
spec->type = FORMAT_TYPE_USHORT;
} else {
if (spec->flags & SIGN)
spec->type = FORMAT_TYPE_INT;
else
spec->type = FORMAT_TYPE_UINT;
}
 
return ++fmt - start;
}
 
/**
* vsnprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @size: The size of the buffer, including the trailing null space
* @fmt: The format string to use
* @args: Arguments for the format string
*
*
* The return value is the number of characters which would
* be generated for the given input, excluding the trailing
* '\0', as per ISO C99. If you want to have the exact
* number of characters written into @buf as return value
* (not including the trailing '\0'), use vscnprintf(). If the
* return is greater than or equal to @size, the resulting
* string is truncated.
*
* Call this function if you are already dealing with a va_list.
* You probably want snprintf() instead.
*/
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
{
unsigned long long num;
char *str, *end, c;
int read;
struct printf_spec spec = {0};
 
/* Reject out-of-range values early. Large positive sizes are
used for unknown buffer sizes. */
if (unlikely((int) size < 0)) {
/* There can be only one.. */
static char warn = 1;
// WARN_ON(warn);
warn = 0;
return 0;
}
 
str = buf;
end = buf + size;
 
/* Make sure end is always >= buf */
if (end < buf) {
end = ((void *)-1);
size = end - buf;
}
 
while (*fmt) {
const char *old_fmt = fmt;
 
read = format_decode(fmt, &spec);
 
fmt += read;
 
switch (spec.type) {
case FORMAT_TYPE_NONE: {
int copy = read;
if (str < end) {
if (copy > end - str)
copy = end - str;
memcpy(str, old_fmt, copy);
}
str += read;
break;
}
 
case FORMAT_TYPE_WIDTH:
spec.field_width = va_arg(args, int);
break;
 
case FORMAT_TYPE_PRECISION:
spec.precision = va_arg(args, int);
break;
 
case FORMAT_TYPE_CHAR:
if (!(spec.flags & LEFT)) {
while (--spec.field_width > 0) {
if (str < end)
*str = ' ';
++str;
 
}
}
c = (unsigned char) va_arg(args, int);
if (str < end)
*str = c;
++str;
while (--spec.field_width > 0) {
if (str < end)
*str = ' ';
++str;
}
break;
 
case FORMAT_TYPE_STR:
str = string(str, end, va_arg(args, char *), spec);
break;
 
case FORMAT_TYPE_PTR:
str = pointer(fmt+1, str, end, va_arg(args, void *),
spec);
while (isalnum(*fmt))
fmt++;
break;
 
case FORMAT_TYPE_PERCENT_CHAR:
if (str < end)
*str = '%';
++str;
break;
 
case FORMAT_TYPE_INVALID:
if (str < end)
*str = '%';
++str;
break;
 
case FORMAT_TYPE_NRCHARS: {
int qualifier = spec.qualifier;
 
if (qualifier == 'l') {
long *ip = va_arg(args, long *);
*ip = (str - buf);
} else if (qualifier == 'Z' ||
qualifier == 'z') {
size_t *ip = va_arg(args, size_t *);
*ip = (str - buf);
} else {
int *ip = va_arg(args, int *);
*ip = (str - buf);
}
break;
}
 
default:
switch (spec.type) {
case FORMAT_TYPE_LONG_LONG:
num = va_arg(args, long long);
break;
case FORMAT_TYPE_ULONG:
num = va_arg(args, unsigned long);
break;
case FORMAT_TYPE_LONG:
num = va_arg(args, long);
break;
case FORMAT_TYPE_SIZE_T:
num = va_arg(args, size_t);
break;
// case FORMAT_TYPE_PTRDIFF:
// num = va_arg(args, ptrdiff_t);
// break;
case FORMAT_TYPE_UBYTE:
num = (unsigned char) va_arg(args, int);
break;
case FORMAT_TYPE_BYTE:
num = (signed char) va_arg(args, int);
break;
case FORMAT_TYPE_USHORT:
num = (unsigned short) va_arg(args, int);
break;
case FORMAT_TYPE_SHORT:
num = (short) va_arg(args, int);
break;
case FORMAT_TYPE_INT:
num = (int) va_arg(args, int);
break;
default:
num = va_arg(args, unsigned int);
}
 
str = number(str, end, num, spec);
}
}
 
if (size > 0) {
if (str < end)
*str = '\0';
else
end[-1] = '\0';
}
 
/* the trailing null byte doesn't count towards the total */
return str-buf;
 
}
 
/**
* snprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @size: The size of the buffer, including the trailing null space
* @fmt: The format string to use
* @...: Arguments for the format string
*
* The return value is the number of characters which would be
* generated for the given input, excluding the trailing null,
* as per ISO C99. If the return is greater than or equal to
* @size, the resulting string is truncated.
*
* See the vsnprintf() documentation for format string extensions over C99.
*/
int snprintf(char * buf, size_t size, const char *fmt, ...)
{
va_list args;
int i;
 
va_start(args, fmt);
i=vsnprintf(buf,size,fmt,args);
va_end(args);
return i;
}
 
/**
* scnprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @size: The size of the buffer, including the trailing null space
* @fmt: The format string to use
* @...: Arguments for the format string
*
* The return value is the number of characters written into @buf not including
* the trailing '\0'. If @size is <= 0 the function returns 0.
*/
 
int scnprintf(char * buf, size_t size, const char *fmt, ...)
{
va_list args;
int i;
 
va_start(args, fmt);
i = vsnprintf(buf, size, fmt, args);
va_end(args);
return (i >= size) ? (size - 1) : i;
}
 
/**
* vsprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @fmt: The format string to use
* @args: Arguments for the format string
*
* The function returns the number of characters written
* into @buf. Use vsnprintf() or vscnprintf() in order to avoid
* buffer overflows.
*
* Call this function if you are already dealing with a va_list.
* You probably want sprintf() instead.
*
* See the vsnprintf() documentation for format string extensions over C99.
*/
int vsprintf(char *buf, const char *fmt, va_list args)
{
return vsnprintf(buf, __INT_MAX__, fmt, args);
}
 
/**
* sprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @fmt: The format string to use
* @...: Arguments for the format string
*
* The function returns the number of characters written
* into @buf. Use snprintf() or scnprintf() in order to avoid
* buffer overflows.
*
* See the vsnprintf() documentation for format string extensions over C99.
*/
int sprintf(char * buf, const char *fmt, ...)
{
va_list args;
int i;
 
va_start(args, fmt);
i=vsnprintf(buf, __INT_MAX__, fmt, args);
va_end(args);
return i;
}
 
static inline
void api_putc(char c)
{
if (c == '\n') api_putc('\r');
 
__asm__ __volatile__(
"int $0x40"
::"a"(63),"b"(1),"c"(c));
}
 
int API print(const char *fmt,...)
{
char buf[256];
va_list args;
int retval;
int i;
 
va_start(args, fmt);
i = vsnprintf(buf, 256, fmt, args);
va_end(args);
 
retval = (i >= 256) ? (256 - 1) : i;
 
for(i = 0; i< retval; i++)
api_putc(buf[i]);
 
return retval;
};
 
 
 
#if 0
/**
* vsscanf - Unformat a buffer into a list of arguments
* @buf: input buffer
* @fmt: format of buffer
* @args: arguments
*/
int vsscanf(const char * buf, const char * fmt, va_list args)
{
const char *str = buf;
char *next;
char digit;
int num = 0;
int qualifier;
int base;
int field_width;
int is_sign = 0;
 
while(*fmt && *str) {
/* skip any white space in format */
/* white space in format matchs any amount of
* white space, including none, in the input.
*/
if (isspace(*fmt)) {
while (isspace(*fmt))
++fmt;
while (isspace(*str))
++str;
}
 
/* anything that is not a conversion must match exactly */
if (*fmt != '%' && *fmt) {
if (*fmt++ != *str++)
break;
continue;
}
 
if (!*fmt)
break;
++fmt;
 
/* skip this conversion.
* advance both strings to next white space
*/
if (*fmt == '*') {
while (!isspace(*fmt) && *fmt)
fmt++;
while (!isspace(*str) && *str)
str++;
continue;
}
 
/* get field width */
field_width = -1;
if (isdigit(*fmt))
field_width = skip_atoi(&fmt);
 
/* get conversion qualifier */
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
*fmt == 'Z' || *fmt == 'z') {
qualifier = *fmt++;
if (unlikely(qualifier == *fmt)) {
if (qualifier == 'h') {
qualifier = 'H';
fmt++;
} else if (qualifier == 'l') {
qualifier = 'L';
fmt++;
}
}
}
base = 10;
is_sign = 0;
 
if (!*fmt || !*str)
break;
 
switch(*fmt++) {
case 'c':
{
char *s = (char *) va_arg(args,char*);
if (field_width == -1)
field_width = 1;
do {
*s++ = *str++;
} while (--field_width > 0 && *str);
num++;
}
continue;
case 's':
{
char *s = (char *) va_arg(args, char *);
if(field_width == -1)
field_width = INT_MAX;
/* first, skip leading white space in buffer */
while (isspace(*str))
str++;
 
/* now copy until next white space */
while (*str && !isspace(*str) && field_width--) {
*s++ = *str++;
}
*s = '\0';
num++;
}
continue;
case 'n':
/* return number of characters read so far */
{
int *i = (int *)va_arg(args,int*);
*i = str - buf;
}
continue;
case 'o':
base = 8;
break;
case 'x':
case 'X':
base = 16;
break;
case 'i':
base = 0;
case 'd':
is_sign = 1;
case 'u':
break;
case '%':
/* looking for '%' in str */
if (*str++ != '%')
return num;
continue;
default:
/* invalid format; stop here */
return num;
}
 
/* have some sort of integer conversion.
* first, skip white space in buffer.
*/
while (isspace(*str))
str++;
 
digit = *str;
if (is_sign && digit == '-')
digit = *(str + 1);
 
if (!digit
|| (base == 16 && !isxdigit(digit))
|| (base == 10 && !isdigit(digit))
|| (base == 8 && (!isdigit(digit) || digit > '7'))
|| (base == 0 && !isdigit(digit)))
break;
 
switch(qualifier) {
case 'H': /* that's 'hh' in format */
if (is_sign) {
signed char *s = (signed char *) va_arg(args,signed char *);
*s = (signed char) simple_strtol(str,&next,base);
} else {
unsigned char *s = (unsigned char *) va_arg(args, unsigned char *);
*s = (unsigned char) simple_strtoul(str, &next, base);
}
break;
case 'h':
if (is_sign) {
short *s = (short *) va_arg(args,short *);
*s = (short) simple_strtol(str,&next,base);
} else {
unsigned short *s = (unsigned short *) va_arg(args, unsigned short *);
*s = (unsigned short) simple_strtoul(str, &next, base);
}
break;
case 'l':
if (is_sign) {
long *l = (long *) va_arg(args,long *);
*l = simple_strtol(str,&next,base);
} else {
unsigned long *l = (unsigned long*) va_arg(args,unsigned long*);
*l = simple_strtoul(str,&next,base);
}
break;
case 'L':
if (is_sign) {
long long *l = (long long*) va_arg(args,long long *);
*l = simple_strtoll(str,&next,base);
} else {
unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*);
*l = simple_strtoull(str,&next,base);
}
break;
case 'Z':
case 'z':
{
size_t *s = (size_t*) va_arg(args,size_t*);
*s = (size_t) simple_strtoul(str,&next,base);
}
break;
default:
if (is_sign) {
int *i = (int *) va_arg(args, int*);
*i = (int) simple_strtol(str,&next,base);
} else {
unsigned int *i = (unsigned int*) va_arg(args, unsigned int*);
*i = (unsigned int) simple_strtoul(str,&next,base);
}
break;
}
num++;
 
if (!next)
break;
str = next;
}
 
/*
* Now we've come all the way through so either the input string or the
* format ended. In the former case, there can be a %n at the current
* position in the format that needs to be filled.
*/
if (*fmt == '%' && *(fmt + 1) == 'n') {
int *p = (int *)va_arg(args, int *);
*p = str - buf;
}
 
return num;
}
#endif