123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602 |
- {
- $Id$
- This file is part of the Free Pascal run time library.
- Copyright (c) 1993,97 by the Free Pascal development team.
- Strings unit for PChar (asciiz/C compatible strings) handling
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program 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.
- **********************************************************************}
- unit strings;
- interface
- { Returns the length of a string }
- function strlen(p : pchar) : longint;
- { Converts a Pascal string to a null-terminated string }
- function strpcopy(d : pchar;const s : string) : pchar;
- { Converts a null-terminated string to a Pascal string }
- function strpas(p : pchar) : string;
- { Copies source to dest, returns a pointer to dest }
- function strcopy(dest,source : pchar) : pchar;
- { Copies at most maxlen bytes from source to dest. }
- { Returns a pointer to dest }
- function strlcopy(dest,source : pchar;maxlen : longint) : pchar;
- { Copies source to dest and returns a pointer to the terminating }
- { null character. }
- function strecopy(dest,source : pchar) : pchar;
- { Returns a pointer tro the terminating null character of p }
- function strend(p : pchar) : pchar;
- { Appends source to dest, returns a pointer do dest}
- function strcat(dest,source : pchar) : pchar;
- { Compares str1 und str2, returns }
- { a value <0 if str1<str2; }
- { 0 when str1=str2 }
- { and a value >0 if str1>str2 }
- function strcomp(str1,str2 : pchar) : longint;
- { The same as strcomp, but at most l characters are compared }
- function strlcomp(str1,str2 : pchar;l : longint) : longint;
- { The same as strcomp but case insensitive }
- function stricomp(str1,str2 : pchar) : longint;
- { Copies l characters from source to dest, returns dest. }
- function strmove(dest,source : pchar;l : longint) : pchar;
- { Appends at most l characters from source to dest }
- function strlcat(dest,source : pchar;l : longint) : pchar;
- { Returns a pointer to the first occurrence of c in p }
- { If c doesn't occur, nil is returned }
- function strscan(p : pchar;c : char) : pchar;
- { Returns a pointer to the last occurrence of c in p }
- { If c doesn't occur, nil is returned }
- function strrscan(p : pchar;c : char) : pchar;
- { converts p to all-lowercase, returns p }
- function strlower(p : pchar) : pchar;
- { converts p to all-uppercase, returns p }
- function strupper(p : pchar) : pchar;
- { The same al stricomp, but at most l characters are compared }
- function strlicomp(str1,str2 : pchar;l : longint) : longint;
- { Returns a pointer to the first occurrence of str2 in }
- { str2 Otherwise returns nil }
- function strpos(str1,str2 : pchar) : pchar;
- { Makes a copy of p on the heap, and returns a pointer to this copy }
- function strnew(p : pchar) : pchar;
- { Allocates L bytes on the heap, returns a pchar pointer to it }
- function stralloc(L : longint) : pchar;
- { Releases a null-terminated string from the heap }
- procedure strdispose(p : pchar);
- implementation
- {$ASMMODE ATT}
- function strcopy(dest,source : pchar) : pchar;
- begin
- asm
- cld
- movl 12(%ebp),%edi
- movl $0xffffffff,%ecx
- xorb %al,%al
- repne
- scasb
- not %ecx
- movl 8(%ebp),%edi
- movl 12(%ebp),%esi
- movl %ecx,%eax
- shrl $2,%ecx
- rep
- movsl
- movl %eax,%ecx
- andl $3,%ecx
- rep
- movsb
- movl 8(%ebp),%eax
- leave
- ret $8
- end;
- end;
- function strecopy(dest,source : pchar) : pchar;
- begin
- asm
- cld
- movl 12(%ebp),%edi
- movl $0xffffffff,%ecx
- xorl %eax,%eax
- repne
- scasb
- not %ecx
- movl 8(%ebp),%edi
- movl 12(%ebp),%esi
- movl %ecx,%eax
- shrl $2,%ecx
- rep
- movsl
- movl %eax,%ecx
- andl $3,%ecx
- rep
- movsb
- movl 8(%ebp),%eax
- decl %edi
- movl %edi,%eax
- leave
- ret $8
- end ['EAX','ESI','EDI'];
- end;
- function strlcopy(dest,source : pchar;maxlen : longint) : pchar;
- begin
- asm
- movl 8(%ebp),%edi
- movl 12(%ebp),%esi
- movl 16(%ebp),%ecx
- cld
- .LSTRLCOPY1:
- lodsb
- stosb
- decl %ecx // Lower maximum
- jz .LSTRLCOPY2 // 0 reached ends
- orb %al,%al
- jnz .LSTRLCOPY1
- movl 8(%ebp),%eax
- leave
- ret $12
- .LSTRLCOPY2:
- xorb %al,%al // If cutted
- stosb // add a #0
- movl 8(%ebp),%eax
- leave
- ret $12
- end ['EAX','ECX','ESI','EDI'];
- end;
- function strlen(p : pchar) : longint;
- begin
- asm
- cld
- movl 8(%ebp),%edi
- movl $0xffffffff,%ecx
- xorl %eax,%eax
- repne
- scasb
- movl $0xfffffffe,%eax
- subl %ecx,%eax
- leave
- ret $4
- end ['EDI','ECX','EAX'];
- end;
- function strend(p : pchar) : pchar;
- begin
- asm
- cld
- movl 8(%ebp),%edi
- movl $0xffffffff,%ecx
- xorl %eax,%eax
- repne
- scasb
- movl %edi,%eax
- decl %eax
- leave
- ret $4
- end ['EDI','ECX','EAX'];
- end;
- function strpcopy(d : pchar;const s : string) : pchar;
- begin
- asm
- pushl %esi // Save ESI
- cld
- movl 8(%ebp),%edi // load destination address
- movl 12(%ebp),%esi // Load Source adress
- movl %edi,%ebx // Set return value
- lodsb // load length in ECX
- movzbl %al,%ecx
- rep
- movsb
- xorb %al,%al // Set #0
- stosb
- movl %ebx,%eax // return value to EAX
- popl %esi
- leave // ... and ready
- ret $8
- end ['EDI','ESI','EBX','EAX','ECX'];
- end;
- {$ASMMODE DIRECT}
- function strpas(p : pchar) : string;
- begin
- asm
- cld
- movl 12(%ebp),%edi
- movl $0xff,%ecx
- xorl %eax,%eax
- movl %edi,%esi
- repne
- scasb
- movl %ecx,%eax
- movl 8(%ebp),%edi
- notb %al
- decl %eax
- stosb
- cmpl $7,%eax
- jl .LStrPas2
- movl %edi,%ecx // Align on 32bits
- negl %ecx
- andl $3,%ecx
- subl %ecx,%eax
- rep
- movsb
- movl %eax,%ecx
- andl $3,%eax
- shrl $2,%ecx
- rep
- movsl
- .LStrPas2:
- movl %eax,%ecx
- rep
- movsb
- end ['ECX','EAX','ESI','EDI'];
- end;
- {$ASMMODE ATT}
- function strcat(dest,source : pchar) : pchar;
- begin
- strcat:=strcopy(strend(dest),source);
- end;
- function strlcat(dest,source : pchar;l : longint) : pchar;
- var
- destend : pchar;
- begin
- destend:=strend(dest);
- l:=l-(destend-dest);
- strlcat:=strlcopy(destend,source,l);
- end;
- function strcomp(str1,str2 : pchar) : longint;
- begin
- asm
- // Find terminating zero
- movl 12(%ebp),%edi
- movl $0xffffffff,%ecx
- cld
- xorl %eax,%eax
- repne
- scasb
- not %ecx
- movl 12(%ebp),%edi
- movl 8(%ebp),%esi
- repe
- cmpsb
- movb -1(%esi),%al
- movzbl -1(%edi),%ecx
- subl %ecx,%eax
- leave
- ret $8
- end ['EAX','ECX','ESI','EDI'];
- end;
- function strlcomp(str1,str2 : pchar;l : longint) : longint;
- begin
- asm
- // Find terminating zero
- movl 12(%ebp),%edi
- movl $0xffffffff,%ecx
- cld
- xorl %eax,%eax
- repne
- scasb
- not %ecx
- cmpl 16(%ebp),%ecx
- jl .LSTRLCOMP1
- movl 16(%ebp),%ecx
- .LSTRLCOMP1:
- movl 12(%ebp),%edi
- movl 8(%ebp),%esi
- repe
- cmpsb
- movb -1(%esi),%al
- movzbl -1(%edi),%ecx
- subl %ecx,%eax
- leave
- ret $12
- end ['EAX','ECX','ESI','EDI'];
- end;
- function stricomp(str1,str2 : pchar) : longint;
- begin
- asm
- // Find terminating zero
- movl 12(%ebp),%edi
- movl $0xffffffff,%ecx
- cld
- xorl %eax,%eax
- repne
- scasb
- not %ecx
- movl 12(%ebp),%edi
- movl 8(%ebp),%esi
- .LSTRICOMP2:
- repe
- cmpsb
- jz .LSTRICOMP3 // If last reached then exit
- movb (%esi),%al
- movzbl (%edi),%ebx
- cmpb $97,%al
- jb .LSTRICOMP1
- cmpb $122,%al
- ja .LSTRICOMP1
- subb $0x20,%al
- .LSTRICOMP1:
- cmpb $97,%bl
- jb .LSTRICOMP4
- cmpb $122,%bl
- ja .LSTRICOMP4
- subb $0x20,%bl
- .LSTRICOMP4:
- subl %ebx,%eax
- jz .LSTRICOMP2 // If still equal, compare again
- .LSTRICOMP3:
- leave
- ret $8
- end ['EAX','ECX','ESI','EDI'];
- end;
- function strlicomp(str1,str2 : pchar;l : longint) : longint;
- begin
- asm
- // Search terminating zero
- movl 12(%ebp),%edi
- movl $0xffffffff,%ecx
- cld
- xorl %eax,%eax
- repne
- scasb
- not %ecx
- cmpl 16(%ebp),%ecx
- jl .LSTRLICOMP5
- movl 16(%ebp),%ecx
- .LSTRLICOMP5:
- movl 12(%ebp),%edi
- movl 8(%ebp),%esi
- .LSTRLICOMP2:
- repe
- cmpsb
- jz .LSTRLICOMP3 // If last reached, exit
- movb (%esi),%al
- movzbl (%edi),%ebx
- cmpb $97,%al
- jb .LSTRLICOMP1
- cmpb $122,%al
- ja .LSTRLICOMP1
- subb $0x20,%al
- .LSTRLICOMP1:
- cmpb $97,%bl
- jb .LSTRLICOMP4
- cmpb $122,%bl
- ja .LSTRLICOMP4
- subb $0x20,%bl
- .LSTRLICOMP4:
- subl %ebx,%eax
- jz .LSTRLICOMP2
- .LSTRLICOMP3:
- leave
- ret $12
- end ['EAX','ECX','ESI','EDI'];
- end;
- function strmove(dest,source : pchar;l : longint) : pchar;
- begin
- move(source^,dest^,l);
- strmove:=dest;
- end;
- function strscan(p : pchar;c : char) : pchar;
- begin
- asm
- movl 8(%ebp),%edi
- movl $0xffffffff,%ecx
- cld
- xorb %al,%al
- repne
- scasb
- not %ecx
- movb 12(%ebp),%al
- movl 8(%ebp),%edi
- repne
- scasb
- movl $0,%eax
- jnz .LSTRSCAN
- movl %edi,%eax
- decl %eax
- .LSTRSCAN:
- leave
- ret $6
- end;
- end;
- function strrscan(p : pchar;c : char) : pchar;
- begin
- asm
- movl 8(%ebp),%edi
- movl $0xffffffff,%ecx
- cld
- xorb %al,%al
- repne
- scasb
- not %ecx
- movb 12(%ebp),%al
- movl 8(%ebp),%edi
- addl %ecx,%edi
- decl %edi
- std
- repne
- scasb
- movl $0,%eax
- jnz .LSTRRSCAN
- movl %edi,%eax
- incl %eax
- .LSTRRSCAN:
- leave
- ret $6
- end;
- end;
- function strupper(p : pchar) : pchar;
- begin
- asm
- movl 8(%ebp),%esi
- movl %esi,%edi
- .LSTRUPPER1:
- lodsb
- cmpb $97,%al
- jb .LSTRUPPER3
- cmpb $122,%al
- ja .LSTRUPPER3
- subb $0x20,%al
- .LSTRUPPER3:
- stosb
- orb %al,%al
- jnz .LSTRUPPER1
- movl 8(%ebp),%eax
- leave
- ret $4
- end;
- end;
- function strlower(p : pchar) : pchar;
- begin
- asm
- movl 8(%ebp),%esi
- movl %esi,%edi
- .LSTRLOWER1:
- lodsb
- cmpb $65,%al
- jb .LSTRLOWER3
- cmpb $90,%al
- ja .LSTRLOWER3
- addb $0x20,%al
- .LSTRLOWER3:
- stosb
- orb %al,%al
- jnz .LSTRLOWER1
- movl 8(%ebp),%eax
- leave
- ret $4
- end;
- end;
- function strpos(str1,str2 : pchar) : pchar;
- var
- p : pchar;
- lstr2 : longint;
- begin
- strpos:=nil;
- p:=strscan(str1,str2^);
- if p=nil then
- exit;
- lstr2:=strlen(str2);
- while p<>nil do
- begin
- if strlcomp(p,str2,lstr2)=0 then
- begin
- strpos:=p;
- exit;
- end;
- inc(longint(p));
- p:=strscan(p,str2^);
- end;
- end;
- procedure strdispose(p : pchar);
- begin
- if p<>nil then
- freemem(p,strlen(p)+1);
- end;
- function strnew(p : pchar) : pchar;
- var
- len : longint;
- begin
- strnew:=nil;
- if (p=nil) or (p^=#0) then
- exit;
- len:=strlen(p)+1;
- getmem(strnew,len);
- if strnew<>nil then
- strmove(strnew,p,len);
- end;
- function stralloc(L : longint) : pchar;
- begin
- StrAlloc:=Nil;
- GetMem (Stralloc,l);
- end;
- end.
- {
- $Log$
- Revision 1.4 1998-05-31 14:15:52 peter
- * force to use ATT or direct parsing
- Revision 1.3 1998/05/30 14:30:22 peter
- * force att reading
- Revision 1.2 1998/05/23 01:14:06 peter
- + I386_ATT switch
- }
|