summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile8
-rw-r--r--include/errno.h13
-rw-r--r--libc/string/Makefile10
-rw-r--r--libc/string/string.c580
-rw-r--r--test/string/Makefile21
-rw-r--r--test/string/testcopy.c108
6 files changed, 257 insertions, 483 deletions
diff --git a/Makefile b/Makefile
index ef5e37c85..f161f2b4c 100644
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,7 @@ DIRS = error getent malloc misc regex stdio \
string termios time sysdeps #rpc
all: libc.a
-libc.a: subdirs headers
+libc.a: headers subdirs
@echo
@echo Finally finished compiling...
@echo
@@ -32,9 +32,9 @@ libc.a: subdirs headers
headers: dummy
- @if [ ! -L "include/asm" ]; then ln -s /usr/src/linux/include/asm include/asm ; fi
- @if [ ! -L "include/net" ]; then ln -s /usr/src/linux/include/net include/net ; fi
- @if [ ! -L "include/linux" ]; then ln -s /usr/src/linux/include/linux include/linux ; fi
+ @if [ ! -L "include/asm" ]; then ln -s /usr/include/asm include/asm ; fi
+ @if [ ! -L "include/net" ]; then ln -s /usr/include/net include/net ; fi
+ @if [ ! -L "include/linux" ]; then ln -s /usr/include/linux include/linux ; fi
tags:
ctags -R
diff --git a/include/errno.h b/include/errno.h
index 498db0fbf..862d0f2cb 100644
--- a/include/errno.h
+++ b/include/errno.h
@@ -4,23 +4,14 @@
#include <features.h>
#include <linux/errno.h>
-#ifdef __USE_BSD
extern int sys_nerr;
extern char *sys_errlist[];
-#endif
-#ifdef __USE_GNU
-extern int _sys_nerr;
-extern char *_sys_errlist[];
-#endif
+#define _sys_nerr sys_nerr
+#define _sys_errlist sys_errlist
extern int errno;
-
-__BEGIN_DECLS
-
extern void perror __P ((__const char* __s));
extern char* strerror __P ((int __errno));
-__END_DECLS
-
#endif
diff --git a/libc/string/Makefile b/libc/string/Makefile
index 3af022365..01d1ee433 100644
--- a/libc/string/Makefile
+++ b/libc/string/Makefile
@@ -26,11 +26,13 @@ LIBC=$(TOPDIR)libc.a
MSRC=string.c
MOBJ=strlen.o strcat.o strcpy.o strcmp.o strncat.o strncpy.o strncmp.o \
- strchr.o strrchr.o strdup.o memcpy.o memccpy.o memchr.o memset.o \
- memcmp.o memmove.o movedata.o
+ strchr.o strrchr.o strdup.o memcpy.o memccpy.o memset.o \
+ memmove.o
+
CSRC=strpbrk.c strsep.c strstr.c strtok.c strcspn.c \
- strspn.c strcasecmp.c strncasecmp.c config.c
-COBJS=$(patsubst %.c,%.o, $(CFILES))
+ config.c memcmp.c memchr.c strspn.c strcasecmp.c \
+ strncasecmp.c
+COBJS=$(patsubst %.c,%.o, $(CSRC))
all: $(MOBJ) $(COBJS) $(LIBC)
diff --git a/libc/string/string.c b/libc/string/string.c
index 0025cec2b..1777ce03c 100644
--- a/libc/string/string.c
+++ b/libc/string/string.c
@@ -6,21 +6,10 @@
#include <string.h>
#include <malloc.h>
-#ifdef __AS386_16__
-#if __FIRST_ARG_IN_AX__
-#define BCC_AX_ASM /* BCC Assembler that can cope with arg in AX */
-#else
-#define BCC_AX_ASM
-#define BCC_ASM /* Use 16 bit BCC assembler */
-#endif
-
-#define PARANOID /* Include extra code for cld and ES register */
-#endif
-
/* This is a basic string package; it includes the most used functions
strlen strcat strcpy strcmp strncat strncpy strncmp strchr strrchr strdup
- memcpy memccpy memchr memset memcmp memmove
+ memcpy memccpy memset memmove
These functions are in seperate files.
strpbrk.o strsep.o strstr.o strtok.o strcspn.o
@@ -30,56 +19,18 @@
/********************** Function strlen ************************************/
#ifdef L_strlen
-size_t strlen(str)
-const char * str;
+size_t strlen(const char * str)
{
-#ifdef BCC_AX_ASM
-#asm
-#if !__FIRST_ARG_IN_AX__
- mov bx,sp
-#endif
- push di
-
-#ifdef PARANOID
- push es
- push ds ; Im not sure if this is needed, so just in case.
- pop es
- cld
-#endif ! This is almost the same as memchr, but it can
- ! stay as a special.
-
-#if __FIRST_ARG_IN_AX__
- mov di,ax
-#else
- mov di,[bx+2]
-#endif
- mov cx,#-1
- xor ax,ax
- repne
- scasb
- not cx
- dec cx
- mov ax,cx
-
-#ifdef PARANOID
- pop es
-#endif
- pop di
-#endasm
-#else
register char * p =(char *) str;
while(*p) p++;
return p-str;
-#endif /* ifdef BCC_AX_ASM */
}
#endif
/********************** Function strcat ************************************/
#ifdef L_strcat
-char * strcat(d, s)
-char *d;
-const char * s;
+char * strcat(char *d, const char * s)
{
(void) strcpy(d+strlen(d), s);
return d;
@@ -89,9 +40,7 @@ const char * s;
/********************** Function strcpy ************************************/
#ifdef L_strcpy
-char * strcpy(d, s)
-char *d;
-const char * s;
+char * strcpy( char *d, const char * s)
{
/* This is probably the quickest on an 8086 but a CPU with a cache will
* prefer to do this in one pass */
@@ -102,68 +51,29 @@ const char * s;
/********************** Function strcmp ************************************/
#ifdef L_strcmp
-int strcmp(d, s)
-const char *d;
-const char * s;
+int strcmp(const char *d, const char * s)
{
- /* There are a number of ways to do this and it really does depend on the
- types of strings given as to which is better, nevertheless the Glib
- method is quite reasonable so we'll take that */
-
-#ifdef BCC_AX_ASM
-#asm
- mov bx,sp
- push di
- push si
-
-#ifdef PARANOID
- push es
- push ds ; Im not sure if this is needed, so just in case.
- pop es
- cld
-#endif
-
-#if __FIRST_ARG_IN_AX__
- mov di,ax ; dest
- mov si,[bx+2] ; source
-#else
- mov di,[bx+2] ; dest
- mov si,[bx+4] ; source
-#endif
-sc_1:
- lodsb
- scasb
- jne sc_2 ; If bytes are diff skip out.
- testb al,al
- jne sc_1 ; If this byte in str1 is nul the strings are equal
- xor ax,ax ; so return zero
- jmp sc_3
-sc_2:
- sbb ax,ax ; Collect correct val (-1,1).
- orb al,#1
-sc_3:
-
-#ifdef PARANOID
- pop es
-#endif
- pop si
- pop di
-#endasm
-#else /* ifdef BCC_AX_ASM */
- register char *s1=(char *)d, *s2=(char *)s, c1,c2;
- while((c1= *s1++) == (c2= *s2++) && c1 );
- return c1 - c2;
-#endif /* ifdef BCC_AX_ASM */
+ register const unsigned char *s1 = (const unsigned char *) d;
+ register const unsigned char *s2 = (const unsigned char *) s;
+ unsigned register char c1, c2;
+
+ do
+ {
+ c1 = (unsigned char) *s1++;
+ c2 = (unsigned char) *s2++;
+ if (c1 == '\0')
+ return c1 - c2;
+ }
+ while (c1 == c2);
+
+ return c1 - c2;
}
#endif
/********************** Function strncat ************************************/
#ifdef L_strncat
-char * strncat(d, s, l)
-char *d;
-const char *s;
-size_t l;
+char * strncat( char *d, const char *s, size_t l)
{
register char *s1=d+strlen(d), *s2;
@@ -182,86 +92,110 @@ size_t l;
/********************** Function strncpy ************************************/
#ifdef L_strncpy
-char * strncpy(d, s, l) /* FIXME need the fast version of this */
-char *d;
-const char *s;
-size_t l;
+char * strncpy ( char *s1, const char *s2, size_t n)
{
- register char *s1=d;
- register const char *s2=s;
- while(l > 0)
- {
- l--;
- if( (*s1++ = *s2++) == '\0')
- break;
- }
-
- /* This _is_ correct strncpy is supposed to zap */
- for(; l>0; l--) *s1++ = '\0';
- return d;
+ register char c;
+ char *s = s1;
+
+ --s1;
+
+ if (n >= 4)
+ {
+ size_t n4 = n >> 2;
+
+ for (;;)
+ {
+ c = *s2++;
+ *++s1 = c;
+ if (c == '\0')
+ break;
+ c = *s2++;
+ *++s1 = c;
+ if (c == '\0')
+ break;
+ c = *s2++;
+ *++s1 = c;
+ if (c == '\0')
+ break;
+ c = *s2++;
+ *++s1 = c;
+ if (c == '\0')
+ break;
+ if (--n4 == 0)
+ goto last_chars;
+ }
+ n = n - (s1 - s) - 1;
+ if (n == 0)
+ return s;
+ goto zero_fill;
+ }
+
+last_chars:
+ n &= 3;
+ if (n == 0)
+ return s;
+
+ do
+ {
+ c = *s2++;
+ *++s1 = c;
+ if (--n == 0)
+ return s;
+ }
+ while (c != '\0');
+
+zero_fill:
+ do
+ *++s1 = '\0';
+ while (--n > 0);
+
+ return s;
}
#endif
/********************** Function strncmp ************************************/
#ifdef L_strncmp
-int strncmp(d, s, l)
-const char *d, *s;
-size_t l;
+int strncmp (const char *s1, const char *s2, size_t n)
{
-#ifdef BCC_AX_ASM
-#asm
- mov bx,sp
- push si
- push di
-
-#ifdef PARANOID
- push es
- push ds ! Im not sure if this is needed, so just in case.
- pop es
- cld
-#endif
-
-#if __FIRST_ARG_IN_AX__
- mov si,ax
- mov di,[bx+2]
- mov cx,[bx+4]
-#else
- mov si,[bx+2] ! Fetch
- mov di,[bx+4]
- mov cx,[bx+6]
-#endif
-
- inc cx
-lp1:
- dec cx
- je lp2
- lodsb
- scasb
- jne lp3
- testb al,al
- jne lp1
-lp2:
- xor ax,ax
- jmp lp4
-lp3:
- sbb ax,ax
- or al,#1
-lp4:
-
-#ifdef PARANOID
- pop es
-#endif
- pop di
- pop si
-#endasm
-#else
- register char c1=0, c2=0;
- while(l-- >0)
- if( (c1= *d++) != (c2= *s++) || c1 == '\0' )
- break;
- return c1-c2;
-#endif
+ unsigned register char c1 = '\0';
+ unsigned register char c2 = '\0';
+
+ if (n >= 4)
+ {
+ size_t n4 = n >> 2;
+ do
+ {
+ c1 = (unsigned char) *s1++;
+ c2 = (unsigned char) *s2++;
+ if (c1 == '\0' || c1 != c2)
+ return c1 - c2;
+ c1 = (unsigned char) *s1++;
+ c2 = (unsigned char) *s2++;
+ if (c1 == '\0' || c1 != c2)
+ return c1 - c2;
+ c1 = (unsigned char) *s1++;
+ c2 = (unsigned char) *s2++;
+ if (c1 == '\0' || c1 != c2)
+ return c1 - c2;
+ c1 = (unsigned char) *s1++;
+ c2 = (unsigned char) *s2++;
+ if (c1 == '\0' || c1 != c2)
+ return c1 - c2;
+ } while (--n4 > 0);
+ n &= 3;
+ }
+
+ while (n > 0)
+ {
+ c1 = (unsigned char) *s1++;
+ c2 = (unsigned char) *s2++;
+ if (c1 == '\0' || c1 != c2)
+ return c1 - c2;
+ n--;
+ }
+
+ return c1 - c2;
}
#endif
@@ -273,37 +207,6 @@ strchr(s, c)
const char * s;
int c;
{
-#ifdef BCC_AX_ASM
-#asm
- mov bx,sp
- push si
-#if __FIRST_ARG_IN_AX__
- mov bx,[bx+2]
- mov si,ax
-#else
- mov si,[bx+2]
- mov bx,[bx+4]
-#endif
- xor ax,ax
-
-#ifdef PARANOID
- cld
-#endif
-
-in_loop:
- lodsb
- cmp al,bl
- jz got_it
- or al,al
- jnz in_loop
- pop si
- ret
-got_it:
- lea ax,[si-1]
- pop si
-
-#endasm
-#else /* ifdef BCC_AX_ASM */
register char ch;
for(;;)
{
@@ -311,7 +214,6 @@ got_it:
if( ch == 0 ) return 0;
s++;
}
-#endif /* ifdef BCC_AX_ASM */
}
#endif
@@ -361,52 +263,9 @@ void *d;
const void *s;
size_t l;
{
-#ifdef BCC_AX_ASM
-#asm
- mov bx,sp
- push di
- push si
-
-#ifdef PARANOID
- push es
- push ds ; Im not sure if this is needed, so just in case.
- pop es
- cld
-#endif
-
-#if __FIRST_ARG_IN_AX__
- mov di,ax ; dest
- mov si,[bx+2] ; source
- mov cx,[bx+4] ; count
-#else
- mov di,[bx+2] ; dest
- mov si,[bx+4] ; source
- mov cx,[bx+6] ; count
-
- mov ax,di
-#endif
- ; If di is odd mov 1 byte before doing word move
- ; this will speed slightly but
- ; NB 8086 has no problem with mis-aligned access.
-
- shr cx,#1 ; Do this faster by doing a mov word
- rep
- movsw
- adc cx,cx ; Retrieve the leftover 1 bit from cflag.
- rep
- movsb
-
-#ifdef PARANOID
- pop es
-#endif
- pop si
- pop di
-#endasm
-#else /* ifdef BCC_AX_ASM */
register char *s1=d, *s2=(char *)s;
for( ; l>0; l--) *((unsigned char*)s1++) = *((unsigned char*)s2++);
return d;
-#endif /* ifdef BCC_AX_ASM */
}
#endif
@@ -427,59 +286,6 @@ size_t l;
}
#endif
-/********************** Function memchr ************************************/
-
-#ifdef L_memchr
-void * memchr(str, c, l)
-const void * str;
-int c;
-size_t l;
-{
-#ifdef BCC_ASM
-#asm
- mov bx,sp
- push di
-
-#ifdef PARANOID
- push es
- push ds ; Im not sure if this is needed, so just in case.
- pop es
- cld
-#endif
-
- mov di,[bx+2]
- mov ax,[bx+4]
- mov cx,[bx+6]
- test cx,cx
- je is_z ! Zero length, do not find.
-
- repne ! Scan
- scasb
- jne is_z ! Not found, ret zero
- dec di ! Adjust ptr
- mov ax,di ! return
- jmp xit
-is_z:
- xor ax,ax
-xit:
-
-#ifdef PARANOID
- pop es
-#endif
- pop di
-#endasm
-#else /* ifdef BCC_ASM */
- register char *p=(char *)str;
- while(l-- > 0)
- {
- if(*p == c) return p;
- p++;
- }
- return 0;
-#endif /* ifdef BCC_ASM */
-}
-#endif
-
/********************** Function memset ************************************/
#ifdef L_memset
@@ -488,109 +294,9 @@ void * str;
int c;
size_t l;
{
-#ifdef BCC_AX_ASM
-#asm
- mov bx,sp
- push di
-
-#ifdef PARANOID
- push es
- push ds ; Im not sure if this is needed, so just in case.
- pop es
- cld
-#endif
-
-#if __FIRST_ARG_IN_AX__
- mov di,ax ; Fetch
- mov ax,[bx+2]
- mov cx,[bx+4]
-#else
- mov di,[bx+2] ; Fetch
- mov ax,[bx+4]
- mov cx,[bx+6]
-#endif
-
-; How much difference does this alignment make ?
-; I don`t think it`s significant cause most will already be aligned.
-
-; test cx,cx ; Zero size - skip
-; je xit
-;
-; test di,#1 ; Line it up
-; je s_1
-; stosb
-; dec cx
-;s_1:
-
- mov ah,al ; Replicate byte
- shr cx,#1 ; Do this faster by doing a sto word
- rep ; Bzzzzz ...
- stosw
- adc cx,cx ; Retrieve the leftover 1 bit from cflag.
-
- rep ; ... z
- stosb
-
-xit:
- mov ax,[bx+2]
-#ifdef PARANOID
- pop es
-#endif
- pop di
-#endasm
-#else /* ifdef BCC_AX_ASM */
register char *s1=str;
while(l-->0) *s1++ = c;
return str;
-#endif /* ifdef BCC_AX_ASM */
-}
-#endif
-
-/********************** Function memcmp ************************************/
-
-#ifdef L_memcmp
-int memcmp(s, d, l)
-const void *s, *d;
-size_t l;
-{
-#ifdef BCC_ASM
-#asm
- mov bx,sp
- push di
- push si
-
-#ifdef PARANOID
- push es
- push ds ! Im not sure if this is needed, so just in case.
- pop es
- cld
-#endif
-
- mov si,[bx+2] ! Fetch
- mov di,[bx+4]
- mov cx,[bx+6]
- xor ax,ax
-
- rep ! Bzzzzz
- cmpsb
- je xit ! All the same!
- sbb ax,ax
- sbb ax,#-1 ! choose +/-1
-xit:
-#ifdef PARANOID
- pop es
-#endif
- pop si
- pop di
-#endasm
-#else /* ifdef BCC_ASM */
- register const char *s1=d, *s2=s;
- register char c1=0, c2=0;
- while(l-- > 0)
- if( (c1= *s1++) != (c2= *s2++) )
- break;
- return c1-c2;
-#endif /* ifdef BCC_ASM */
}
#endif
@@ -615,60 +321,6 @@ size_t l;
}
#endif
-/********************** Function movedata ***********************************/
-
-#ifdef L_movedata
-
-/* NB There isn't any C version of this function ... */
-
-#ifdef BCC_AX_ASM
-void
-__movedata(srcseg, srcoff, destseg, destoff, len)
-unsigned int srcseg, srcoff, destseg, destoff, len;
-{
-#asm
- push bp
- mov bp,sp
- push si
- push di
- push ds
-#ifdef PARANOID
- push es
- cld
-#endif
-
- ! sei ! Are we _really_ paranoid ?
-
-#if !__FIRST_ARG_IN_AX__
- mov ds,[bp+4] ! Careful, [bp+xx] is SS based.
- mov si,[bp+6]
- mov es,[bp+8]
- mov di,[bp+10]
- mov cx,[bp+12]
-#else
- mov ds,ax
- mov si,[bp+4]
- mov es,[bp+6]
- mov di,[bp+8]
- mov cx,[bp+10]
-#endif
- rep
- movsb
-
- ! cli ! Are we _really_ paranoid ?
-
-#ifdef PARANOID
- pop es
-#endif
- pop ds
- pop di
- pop si
- pop bp
-#endasm
-}
-#endif
-
-#endif
/********************** THE END ********************************************/
diff --git a/test/string/Makefile b/test/string/Makefile
index b3021e0fc..5384c9dec 100644
--- a/test/string/Makefile
+++ b/test/string/Makefile
@@ -20,6 +20,7 @@ endif
STRIP = $(STRIPTOOL) --remove-section=.note --remove-section=.comment $@
TARGETS=string string_glibc
+TARGETS+=testcopy testcopy_glibc
all: $(TARGETS)
@@ -43,6 +44,26 @@ string_glibc: string.c Makefile $(TOPDIR)libc.a
-./$@
-@ echo " "
+testcopy: testcopy.c Makefile $(TOPDIR)libc.a
+ -@ echo "-------"
+ -@ echo " "
+ -@ echo "Compiling vs uCLibc: "
+ -@ echo " "
+ $(CC) $(XCFLAGS) -c $< -o $@.o
+ $(CC) $(XLDFLAGS) $@.o -o $@ $(EXTRA_LIBS)
+ -./$@
+ -@ echo " "
+
+testcopy_glibc: testcopy.c Makefile $(TOPDIR)libc.a
+ -@ echo "-------"
+ -@ echo " "
+ -@ echo "Compiling vs GNU libc: "
+ -@ echo " "
+ $(CC) $(YCFLAGS) -c $< -o $@.o
+ $(CC) $(YLDFLAGS) --static $@.o -o $@
+ -./$@
+ -@ echo " "
+
clean:
rm -f *.[oa] *~ core $(TARGETS)
diff --git a/test/string/testcopy.c b/test/string/testcopy.c
new file mode 100644
index 000000000..02d193779
--- /dev/null
+++ b/test/string/testcopy.c
@@ -0,0 +1,108 @@
+/* Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+
+int main(int argc, char **argv)
+{
+ char *mem, *memp;
+ char *rand_mem;
+ char *lo_around, *hi_around;
+ int size, max_size;
+ int src_off, dst_off;
+ int i;
+ int space_around = 10;
+
+ max_size = 256;
+
+ mem = malloc (max_size + 2 * max_size + 2 * space_around);
+ rand_mem = malloc (max_size);
+ lo_around = malloc (space_around);
+ hi_around = malloc (space_around);
+ memp = mem + space_around;
+
+ /* Fill RAND_MEM with random bytes, each non-zero. */
+ for (i = 0; i < max_size; i++)
+ {
+ int x;
+ do
+ x = rand ();
+ while (x == 0);
+ rand_mem[i] = x;
+ }
+
+ for (size = 0; size < max_size; size++)
+ {
+ printf("phase %d\n", size);
+ for (src_off = 0; src_off <= 16; src_off++)
+ {
+ for (dst_off = 0; dst_off <= 16; dst_off++)
+ {
+ /* Put zero around the intended destination, to check
+ that it's not clobbered. */
+ for (i = 1; i < space_around; i++)
+ {
+ memp[dst_off - i] = 0;
+ memp[dst_off + size - 1 + i] = 0;
+ }
+
+ /* Fill the source area with known contents. */
+ for (i = 0; i < size; i++)
+ memp[src_off + i] = rand_mem[i];
+
+ /* Remember the contents around the destination area.
+ (It might not be what we wrote some lines above, since
+ the src area and the dst area overlap.) */
+ for (i = 1; i < space_around; i++)
+ {
+ lo_around[i] = memp[dst_off - i];
+ hi_around[i] = memp[dst_off + size - 1 + i];
+ }
+
+ memmove (memp + dst_off, memp + src_off, size);
+
+ /* Check that the destination area has the same
+ contents we wrote to the source area. */
+ for (i = 0; i < size; i++)
+ {
+ if (memp[dst_off + i] != rand_mem[i])
+ abort ();
+ }
+
+ /* Check that the area around the destination is not
+ clobbered. */
+ for (i = 1; i < space_around; i++)
+ {
+ if (memp[dst_off - i] != lo_around[i])
+ abort ();
+ if (memp[dst_off + size - 1 + i] != hi_around[i])
+ abort ();
+ }
+ }
+ }
+ }
+
+ puts ("Test succeeded.");
+
+ return 0;
+}