import from github

This commit is contained in:
2022-05-19 17:14:13 +00:00
parent 5247c34f50
commit ab32b30591
12612 changed files with 1905035 additions and 83 deletions

50
agbcc/libc/string/bcmp.c Normal file
View File

@ -0,0 +1,50 @@
/*
FUNCTION
<<bcmp>>---compare two memory areas
INDEX
bcmp
ANSI_SYNOPSIS
#include <string.h>
int bcmp(const char *<[s1]>, const char *<[s2]>, size_t <[n]>);
TRAD_SYNOPSIS
#include <string.h>
int bcmp(<[s1]>, <[s2]>, <[n]>)
char *<[s1]>;
char *<[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]>.
This function is identical to <<memcmp>>.
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
<<bcmp>> requires no supporting OS subroutines.
QUICKREF
bcmp ansi pure
*/
#include <string.h>
int
_DEFUN (bcmp, (m1, m2, n),
_CONST char *m1 _AND
_CONST char *m2 _AND
size_t n)
{
return memcmp (m1, m2, n);
}

38
agbcc/libc/string/bcopy.c Normal file
View File

@ -0,0 +1,38 @@
/*
FUNCTION
<<bcopy>>---copy memory regions
ANSI_SYNOPSIS
#include <string.h>
void bcopy(const char *<[in]>, char *<[out]>, size_t <[n]>);
TRAD_SYNOPSIS
void bcopy(<[in]>, <[out]>, <[n]>
char *<[in]>;
char *<[out]>;
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]>.
This function is implemented in term of <<memmove>>.
PORTABILITY
<<bcopy>> requires no supporting OS subroutines.
QUICKREF
bcopy - pure
*/
#include <string.h>
void
_DEFUN (bcopy, (b1, b2, length),
_CONST char *b1 _AND
char *b2 _AND
size_t length)
{
memmove ((_PTR) b2, (_PTR) b1, length);
}

42
agbcc/libc/string/bzero.c Normal file
View File

@ -0,0 +1,42 @@
/*
FUNCTION
<<bzero>>---initialize memory to zero
INDEX
bzero
ANSI_SYNOPSIS
#include <string.h>
void bzero(char *<[b]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.h>
void bzero(<[b]>, <[length]>)
char *<[b]>;
size_t <[length]>;
DESCRIPTION
<<bzero>> initializes <[length]> bytes of memory, starting at address
<[b]>, to zero.
RETURNS
<<bzero>> does not return a result.
PORTABILITY
<<bzero>> is in the Berkeley Software Distribution.
Neither ANSI C nor the System V Interface Definition (Issue 2) require
<<bzero>>.
<<bzero>> requires no supporting OS subroutines.
*/
#include <string.h>
_VOID
_DEFUN (bzero, (b, length),
char *b _AND
size_t length)
{
while (length--)
*b++ = 0;
}

44
agbcc/libc/string/index.c Normal file
View File

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

143
agbcc/libc/string/memchr.c Normal file
View File

@ -0,0 +1,143 @@
/*
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, <<NULL>> 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
_PTR
_DEFUN (memchr, (src_void, c, length),
_CONST _PTR src_void _AND
int c _AND
size_t length)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
_CONST unsigned char *src = (_CONST unsigned char *) src_void;
c &= 0xff;
while (length--)
{
if (*src == c)
return (char *) src;
src++;
}
return NULL;
#else
_CONST unsigned char *src = (_CONST unsigned char *) src_void;
unsigned long *asrc;
unsigned long buffer;
unsigned long mask;
int i, j;
c &= 0xff;
/* If the size is small, or src is unaligned, then
use the bytewise loop. We can hope this is rare. */
if (!TOO_SMALL (length) && !UNALIGNED (src))
{
/* The fast code reads the ASCII 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 NULL in the
result. */
asrc = (unsigned long*) src;
mask = 0;
for (i = 0; i < LBLOCKSIZE; i++)
mask = (mask << 8) + c;
while (length >= LBLOCKSIZE)
{
buffer = *asrc;
buffer ^= mask;
if (DETECTNULL (buffer))
{
src = (unsigned char*) asrc;
for ( j = 0; j < LBLOCKSIZE; j++ )
{
if (*src == c)
return (char*) src;
src++;
}
}
length -= LBLOCKSIZE;
asrc++;
}
/* If there are fewer than LBLOCKSIZE characters left,
then we resort to the bytewise loop. */
src = (unsigned char*) asrc;
}
while (length--)
{
if (*src == c)
return (char*) src;
src++;
}
return NULL;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

113
agbcc/libc/string/memcmp.c Normal file
View File

@ -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 = (char*)a1;
s2 = (char*)a2;
}
while (n--)
{
if (*s1 != *s2)
return *s1 - *s2;
s1++;
s2++;
}
return 0;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

111
agbcc/libc/string/memcpy.c Normal file
View File

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

143
agbcc/libc/string/memmove.c Normal file
View File

@ -0,0 +1,143 @@
/*
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;
int len = length;
if (src < dst && dst < src + len)
{
/* Destructive overlap...have to copy backwards */
src += len;
dst += len;
while (len--)
{
*--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(len) && !UNALIGNED (src, dst))
{
aligned_dst = (long*)dst;
aligned_src = (long*)src;
/* Copy 4X long words at a time if possible. */
while (len >= BIGBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
len -= BIGBLOCKSIZE;
}
/* Copy one long word at a time if possible. */
while (len >= LITTLEBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
len -= LITTLEBLOCKSIZE;
}
/* Pick up any residual with a byte copier. */
dst = (char*)aligned_dst;
src = (char*)aligned_src;
}
while (len--)
{
*dst++ = *src++;
}
}
return dst_void;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

110
agbcc/libc/string/memset.c Normal file
View File

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

View File

@ -0,0 +1,44 @@
/*
FUNCTION
<<rindex>>---reverse search for character in string
INDEX
rindex
ANSI_SYNOPSIS
#include <string.h>
char * rindex(const char *<[string]>, int <[c]>);
TRAD_SYNOPSIS
#include <string.h>
char * rindex(<[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).
This function is identical to <<strrchr>>.
RETURNS
Returns a pointer to the located character, or a null pointer
if <[c]> does not occur in <[string]>.
PORTABILITY
<<rindex>> requires no supporting OS subroutines.
QUICKREF
rindex - pure
*/
#include <string.h>
char *
_DEFUN (rindex, (s, c),
_CONST char *s _AND
int c)
{
return strrchr (s, c);
}

View File

@ -0,0 +1,56 @@
/*
FUNCTION
<<strcasecmp>>---case insensitive character string compare
INDEX
strcasecmp
ANSI_SYNOPSIS
#include <string.h>
int strcasecmp(const char *<[a]>, const char *<[b]>);
TRAD_SYNOPSIS
#include <string.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 upper case), <<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 <string.h>
#include <ctype.h>
int
_DEFUN (strcasecmp, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
while (*s1 != '\0' && tolower(*s1) == tolower(*s2))
{
s1++;
s2++;
}
return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);
}

104
agbcc/libc/string/strcat.c Normal file
View File

@ -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 */
}

108
agbcc/libc/string/strchr.c Normal file
View File

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

106
agbcc/libc/string/strcmp.c Normal file
View File

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

View File

@ -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);
}

View File

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

View File

@ -0,0 +1,54 @@
/*
FUNCTION
<<strcspn>>---count chars 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;
}

View File

@ -0,0 +1,615 @@
/***
**** 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]>);
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 E2BIG
Arg list too long
o EACCES
Permission denied
o EADV
Advertise error
o EAGAIN
No more processes
o EBADF
Bad file number
o EBADMSG
Bad message
o EBUSY
Device or resource busy
o ECHILD
No children
o ECOMM
Communication error
o EDEADLK
Deadlock
o EEXIST
File exists
o EDOM
Math argument
o EFAULT
Bad address
o EFBIG
File too large
o EIDRM
Identifier removed
o EINTR
Interrupted system call
o EINVAL
Invalid argument
o EIO
I/O error
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 EMULTIHOP
Multihop attempted
o ENAMETOOLONG
File or path name too long
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 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 ENOTDIR
Not a directory
o ENOTEMPTY
Directory not empty
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 ERANGE
Result too large
o EREMOTE
Resource is remote
o EROFS
Read-only file system
o ESPIPE
Illegal seek
o ESRCH
No such process
o ESRMNT
Srmount error
o ETIME
Stream ioctl timeout
o ETXTBSY
Text file busy
o EXDEV
Cross-device link
o-
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, ANSI C
declares that subsequent calls to <<strerror>> may overwrite the
result string; therefore portable code cannot depend on the reentrancy
of this subroutine.
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 <[errnum]> as its argument.
<<_user_strerror>> takes one argument of type <[int]>, and returns a
character pointer. If <[errnum]> is unknown to <<_user_strerror>>,
<<_user_strerror>> returns <[NULL]>. The default <<_user_strerror>>
returns <[NULL]> for all input values.
<<strerror>> requires no supporting OS subroutines.
QUICKREF
strerror ansi pure
*/
#include <errno.h>
#include <string.h>
char *
_DEFUN (strerror, (errnum),
int errnum)
{
char *error;
extern char *_user_strerror _PARAMS ((int));
switch (errnum)
{
/* 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 EBADF
case EBADF:
error = "Bad file number";
break;
#endif
#ifdef ECHILD
case ECHILD:
error = "No children";
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 EISDIR
case EISDIR:
error = "Is a directory";
break;
#endif
#ifdef EINVAL
case EINVAL:
error = "Invalid argument";
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 ENOSPC
case ENOSPC:
error = "No space left on device";
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 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 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
default:
if ((error = _user_strerror (errnum)) == 0)
error = "";
break;
}
return error;
}

View File

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

View File

@ -0,0 +1,50 @@
/*
FUNCTION
<<strlwr>>---force string to lower case
INDEX
strlwr
ANSI_SYNOPSIS
#include <string.h>
char *strlwr(char *<[a]>);
TRAD_SYNOPSIS
#include <string.h>
char *strlwr(<[a]>)
char *<[a]>;
DESCRIPTION
<<strlwr>> converts each characters in the string at <[a]> to
lower case.
RETURNS
<<strlwr>> returns its argument, <[a]>.
PORTABILITY
<<strlwr>> is not widely portable.
<<strlwr>> requires no supporting OS subroutines.
QUICKREF
strlwr
*/
#include <string.h>
#include <ctype.h>
char *
strlwr (a)
char *a;
{
char *ret = a;
while (*a != '\0')
{
if (isupper (*a))
*a = tolower (*a);
++a;
}
return ret;
}

View File

@ -0,0 +1,64 @@
/*
FUNCTION
<<strncasecmp>>---case insensitive character string compare
INDEX
strncasecmp
ANSI_SYNOPSIS
#include <string.h>
int strncasecmp(const char *<[a]>, const char * <[b]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.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 upper case), <<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 <string.h>
#include <ctype.h>
int
_DEFUN (strncasecmp, (s1, s2, n),
_CONST char *s1 _AND
_CONST char *s2 _AND
size_t n)
{
if (n == 0)
return 0;
while (n-- != 0 && tolower(*s1) == tolower(*s2))
{
if (n == 0 || *s1 == '\0' || *s2 == '\0')
break;
s1++;
s2++;
}
return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);
}

115
agbcc/libc/string/strncat.c Normal file
View File

@ -0,0 +1,115 @@
/*
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 */
}

122
agbcc/libc/string/strncmp.c Normal file
View File

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

125
agbcc/libc/string/strncpy.c Normal file
View File

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

View File

@ -0,0 +1,58 @@
/*
FUNCTION
<<strpbrk>>---find chars 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;
}

View File

@ -0,0 +1,61 @@
/*
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;
char c = i;
while (*s)
{
if (*s == c)
{
last = s;
}
s++;
}
if (*s == c)
{
last = s;
}
return (char *) last;
}

View File

@ -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;
}

View File

@ -0,0 +1,73 @@
/*
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 occurence 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, the <[s1]> is returned.
PORTABILITY
<<strstr>> is ANSI C.
<<strstr>> requires no supporting OS subroutines.
QUICKREF
strstr ansi pure
*/
#include <string.h>
char *
_DEFUN (strstr, (searchee, lookfor),
_CONST char *searchee _AND
_CONST char *lookfor)
{
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;
}

View File

@ -0,0 +1,76 @@
/*
FUNCTION
<<strtok>>---get next token from a string
INDEX
strtok
INDEX
strtok_r
ANSI_SYNOPSIS
#include <string.h>
char *strtok(char *<[source]>, const char *<[delimiters]>)
char *strtok_r(char *<[source]>, const char *<[delimiters]>,
char **<[lasts]>)
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]>;
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 NUL 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.
RETURNS
<<strtok>> returns a pointer to the next token, or <<NULL>> if
no more tokens can be found.
NOTES
<<strtok>> is unsafe for multi-thread applications. <<strtok_r>>
is MT-Safe and should be used instead.
PORTABILITY
<<strtok>> is ANSI C.
<<strtok>> requires no supporting OS subroutines.
QUICKREF
strtok ansi impure
*/
#include <string.h>
#include <_ansi.h>
#include <reent.h>
#ifndef _REENT_ONLY
char *
_DEFUN (strtok, (s, delim),
register char *s _AND
register const char *delim)
{
return strtok_r (s, delim, &(_REENT->_new._reent._strtok_last));
}
#endif

View File

@ -0,0 +1,85 @@
/*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <string.h>
char *
_DEFUN (strtok_r, (s, delim, lasts),
register char *s _AND
register const char *delim _AND
char **lasts)
{
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)
goto cont;
}
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 */
}

View File

@ -0,0 +1,49 @@
/*
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 characters in the string at <[a]> to
upper case.
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 *
strupr (a)
char *a;
{
char *ret = a;
while (*a != '\0')
{
if (islower (*a))
*a = toupper (*a);
++a;
}
return ret;
}

View File

@ -0,0 +1,75 @@
/*
FUNCTION
<<strxfrm>>---transform string
INDEX
strxfrm
ANSI_SYNOPSIS
#include <string.h>
size_t strxfrm(char *<[s1]>, const char *<[s2]>, size_t <[n]>);
TRAD_SYNOPSIS
#include <string.h>
size_t strxfrm(<[s1]>, <[s2]>, <[n]>);
char *<[s1]>;
char *<[s2]>;
size_t <[n]>;
DESCRIPTION
This function transforms the string pointed to by <[s2]> and
places the resulting string into the array pointed to by
<[s1]>. The transformation is such that if the <<strcmp>>
function is applied to the two transformed strings, it returns
a value greater than, equal to, or less than zero,
correspoinding to the result of a <<strcoll>> function applied
to the same two original strings.
No more than <[n]> characters are placed into the resulting
array pointed to by <[s1]>, including the terminating null
character. If <[n]> is zero, <[s1]> may be a null pointer. If
copying takes place between objects that overlap, the behavior
is undefined.
With a C locale, this function just copies.
RETURNS
The <<strxfrm>> function returns the length of the transformed string
(not including the terminating null character). If the value returned
is <[n]> or more, the contents of the array pointed to by
<[s1]> are indeterminate.
PORTABILITY
<<strxfrm>> is ANSI C.
<<strxfrm>> requires no supporting OS subroutines.
QUICKREF
strxfrm ansi pure
*/
#include <string.h>
size_t
_DEFUN (strxfrm, (s1, s2, n),
char *s1 _AND
_CONST char *s2 _AND
size_t n)
{
size_t res;
res = 0;
while (n-- > 0)
{
if ((*s1++ = *s2++) != '\0')
++res;
else
return res;
}
while (*s2)
{
++s2;
++res;
}
return res;
}

View File

@ -0,0 +1,8 @@
#include <_ansi.h>
char *
_DEFUN(_user_strerror, (errnum),
int errnum)
{
return 0;
}