diff options
| -rw-r--r-- | Makefile | 8 | ||||
| -rw-r--r-- | include/errno.h | 13 | ||||
| -rw-r--r-- | libc/string/Makefile | 10 | ||||
| -rw-r--r-- | libc/string/string.c | 580 | ||||
| -rw-r--r-- | test/string/Makefile | 21 | ||||
| -rw-r--r-- | test/string/testcopy.c | 108 | 
6 files changed, 257 insertions, 483 deletions
| @@ -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; +} | 
