|
@@ -6,21 +6,10 @@
|
|
|
#include <string.h>
|
|
|
#include <malloc.h>
|
|
|
|
|
|
-#ifdef __AS386_16__
|
|
|
-#if __FIRST_ARG_IN_AX__
|
|
|
-#define BCC_AX_ASM
|
|
|
-#else
|
|
|
-#define BCC_AX_ASM
|
|
|
-#define BCC_ASM
|
|
|
-#endif
|
|
|
-
|
|
|
-#define PARANOID
|
|
|
-#endif
|
|
|
-
|
|
|
|
|
|
|
|
|
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 @@
|
|
|
|
|
|
|
|
|
#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
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#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;
|
|
|
|
|
|
|
|
|
#ifdef L_strcpy
|
|
|
-char * strcpy(d, s)
|
|
|
-char *d;
|
|
|
-const char * s;
|
|
|
+char * strcpy( char *d, const char * s)
|
|
|
{
|
|
|
|
|
|
* prefer to do this in one pass */
|
|
@@ -102,68 +51,29 @@ const char * s;
|
|
|
|
|
|
|
|
|
#ifdef L_strcmp
|
|
|
-int strcmp(d, s)
|
|
|
-const char *d;
|
|
|
-const char * s;
|
|
|
+int strcmp(const char *d, const char * s)
|
|
|
{
|
|
|
-
|
|
|
- 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
|
|
|
- register char *s1=(char *)d, *s2=(char *)s, c1,c2;
|
|
|
- while((c1= *s1++) == (c2= *s2++) && c1 );
|
|
|
- return c1 - c2;
|
|
|
-#endif
|
|
|
+ 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
|
|
|
|
|
|
|
|
|
|
|
|
#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;
|
|
|
|
|
|
|
|
|
#ifdef L_strncpy
|
|
|
-char * strncpy(d, s, l)
|
|
|
-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;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- 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
|
|
|
|
|
|
|
|
|
|
|
|
#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
|
|
|
register char ch;
|
|
|
for(;;)
|
|
|
{
|
|
@@ -311,7 +214,6 @@ got_it:
|
|
|
if( ch == 0 ) return 0;
|
|
|
s++;
|
|
|
}
|
|
|
-#endif
|
|
|
}
|
|
|
#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
|
|
|
register char *s1=d, *s2=(char *)s;
|
|
|
for( ; l>0; l--) *((unsigned char*)s1++) = *((unsigned char*)s2++);
|
|
|
return d;
|
|
|
-#endif
|
|
|
}
|
|
|
#endif
|
|
|
|
|
@@ -427,59 +286,6 @@ size_t l;
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-#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
|
|
|
- register char *p=(char *)str;
|
|
|
- while(l-- > 0)
|
|
|
- {
|
|
|
- if(*p == c) return p;
|
|
|
- p++;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-#endif
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
|
|
|
|
|
|
#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
|
|
|
register char *s1=str;
|
|
|
while(l-->0) *s1++ = c;
|
|
|
return str;
|
|
|
-#endif
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-#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
|
|
|
- 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
|
|
|
}
|
|
|
#endif
|
|
|
|
|
@@ -615,60 +321,6 @@ size_t l;
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-#ifdef L_movedata
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-#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
|
|
|
|
|
|
|
|
|
|