1
; Copyright (C) 2000, 2003 MySQL AB
3
; This library is free software; you can redistribute it and/or
4
; modify it under the terms of the GNU Library General Public
5
; License as published by the Free Software Foundation; version 2
8
; This library is distributed in the hope that it will be useful,
9
; but WITHOUT ANY WARRANTY; without even the implied warranty of
10
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
; Library General Public License for more details.
13
; You should have received a copy of the GNU Library General Public
14
; License along with this library; if not, write to the Free
15
; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18
; Note that if you don't have a macro assembler (like MASM) to compile
19
; this file, you can instead compile all *.c files in the string
22
TITLE Stringfunctions that we use often at MSDOS / Intel 8086
34
q_movs MACRO ; as rep movsb but quicker
36
rep movsw ; Move 2 bytes at a time
38
rep movsb ; Move last byte if any
41
q_stos MACRO ; as rep stosb but quicker
42
mov ah,al ; For word store
44
rep stosw ; Move 2 bytes at a time
46
rep stosb ; Move last byte if any
49
ifndef ZTC ; If not using ZORTECH compiler
62
les di,DWORD PTR [bp+8] ; s2
63
lds si,DWORD PTR [bp+4] ; s1
64
mov cx,WORD PTR [bp+12] ; Length of memory-area
65
jcxz @F ; Length = 0, return same
67
repe cmpsb ; Compare strings
69
inc cx ; return matchpoint +1
70
@@: mov ax,cx ; Return 0 if match, else pos from end
79
; Find a char in a string
81
; Ret: pointer to found char or NullS
84
ifdef better_stringfunctions ; Breaks window linkage (broken linking)
88
mov bx,bp ; Save bp and di
91
les di,DWORD PTR [bp+4] ; str
92
mov ah,BYTE PTR [bp+8] ; search
93
xor al,al ; for scasb to find end
109
; Find length of string
118
les di,DWORD PTR ss:[bx+4] ; Str
119
xor al,al ; Find end of string
122
repne scasb ; Find strend or length
123
inc cx ; Calc strlength
126
mov di,dx ; Restore register
135
; ret: end-null of to
145
les di,DWORD PTR [bp+4] ; dst
146
lds si,DWORD PTR [bp+8] ; src
152
lea ax,WORD PTR [di-1] ; Set DX:AX to point at last null
162
; Fill a area of memory with a walue
163
; Args: to,length,fillchar
168
mov bx,sp ; Get args through BX
169
mov al,BYTE PTR ss:[bx+10] ; Fill
172
les di,DWORD PTR ss:[bx+4] ; Memory pointer
173
mov cx,WORD PTR ss:[bx+8] ; Length
181
; Fill a area with null
186
mov bx,sp ; Get args through BX
187
mov al,0 ; Fill with null
195
; Args: to,from,length
205
lds si,DWORD PTR [bp+8] ; from
206
les di,DWORD PTR [bp+4] ; to
207
mov cx,WORD PTR [bp+12] ; Length of memory-area
209
rep movsb ; Not q_movs because overlap ?
218
; Move a alligned, not overlapped, by (long) divided memory area
219
; Args: to,from,length
229
lds si,DWORD PTR [bp+8] ; from
230
les di,DWORD PTR [bp+4] ; to
231
mov cx,WORD PTR [bp+12] ; Length of memory-area
233
inc cx ; fix if not divisible with word
235
rep movsw ; Move 2 bytes at a time
244
; Move a string from higher to lower
245
; Arg from+1,to+1,length
255
lds si,DWORD PTR [bp+8] ; from
256
les di,DWORD PTR [bp+4] ; to
257
mov cx,WORD PTR [bp+12] ; Length of memory-area
258
dec di ; Don't move last arg
261
rep movsb ; Not q_movs because overlap ?
262
cld ; C compilator want cld
271
; Append fillchars to string
272
; Args: dest,len,fill
280
les di,DWORD PTR [bp+4] ; Memory pointer
281
mov cx,WORD PTR [bp+8] ; Length
282
sub al,al ; Find end of string
285
jnz sa_99 ; String to long, shorten it
286
mov al,BYTE PTR [bp+10] ; Fillchar
287
dec di ; Point at end null
288
inc cx ; rep made one dec for null-char
289
q_stos ; Store al in string
290
sa_99: mov BYTE PTR es:[di],0 ; End of string
297
; Find if string contains any char in another string
299
; Ret: Pointer to first found char in str
304
mov bx,bp ; Save bp and di in regs
309
lds si,DWORD PTR [bp+4] ; str
310
les di,DWORD PTR [bp+8] ; Set
311
mov cx,di ; Save for loop
312
xor ah,ah ; For endtest
316
jz sc_fo ; Found char
317
sc_20: cmp ah,es:[di] ; Test if null
318
jnz sc_10 ; Not end of set yet
319
inc si ; Next char in str
320
mov di,cx ; es:di = Set
321
sc_60: mov al,ds:[si] ; Test if this char exist
323
jnz sc_20 ; Not end of string
324
sub si,si ; Return Null
326
sc_fo: mov ax,si ; Char found here
328
mov dx,ds ; Seg of found char
336
; Found end of string
338
; ret: Pointer to end null
345
les di,DWORD PTR ss:[bx+4] ; str
347
sub al,al ; Find end of string
350
lea ax,WORD PTR [di-1] ; Endpos i DX:AX
357
; Make a string with len fill-chars and endnull
358
; Args: dest,len,fill
367
les di,DWORD PTR [bp+4] ; Memory pointer
368
mov cx,WORD PTR [bp+8] ; Length
369
mov al,BYTE PTR [bp+10] ; Fill
372
mov BYTE PTR es:[di],0 ; End NULL
373
mov ax,di ; End i DX:AX
381
; Find a char in or end of a string
383
; Ret: pointer to found char or NullS
388
mov bx,bp ; Save bp and di
391
les di,DWORD PTR [bp+4] ; str
392
mov ah,BYTE PTR [bp+8] ; search
393
xor al,al ; for scasb to find end
399
dec di ; Not found, point at end of string
408
; Test if string has a given suffix
414
mov bx,sp ; Arguments through bx
417
les di,DWORD PTR ss:[bx+8] ; s2
418
lds si,DWORD PTR ss:[bx+4] ; s1
419
mov ax,1 ; Ok and zero-test
422
jz suf_ok ; End of string; found suffix
423
cmpsb ; Compare strings
424
jz @B ; Same, possible prefix
425
xor ax,ax ; Not suffix
433
; Find a substring in string
444
lds si,DWORD PTR [bp+4] ; str
445
les di,DWORD PTR [bp+8] ; search
447
inc cx ; CX = search+1
448
mov ah,es:[di] ; AH = First char in search
451
sf_00: mov si,dx ; si = Current str-pos
452
sf_10: mov al,ds:[si] ; Test if this char exist
454
jz sf_90 ; End of string, didn't find search
457
jnz sf_10 ; Didn't find first char, continue
458
mov dx,si ; Save str-pos in DX
460
sf_20: cmp BYTE PTR es:[di],0
461
jz sf_fo ; Found substring
464
jmp sf_00 ; Next str-pos
466
sf_90: sub dx,dx ; Return Null
468
inc dx ; Because of following dec
469
sf_fo: mov ax,dx ; Char found here
470
dec ax ; Pointed one after
480
; Make a string of len length from another string
481
; Arg: dst,src,length
492
les di,DWORD PTR [bp+4] ; dst
493
lds si,DWORD PTR [bp+8] ; src
494
mov cx,WORD PTR [bp+12] ; Length of memory-area
495
xor al,al ; For test of end-null
496
jcxz sm_90 ; Nothing to move, put zero at end.
499
@@: cmp al,ds:[si] ; Next char to move
501
jz sm_99 ; last char, we are ready
502
loop @B ; Continue moving
503
sm_90: mov BYTE PTR es:[di],al ; Set end pos
504
inc di ; Fix that di points at end null
505
sm_99: dec di ; di points now at end null
506
mov ax,di ; Ret value in DX:AX
516
; Find length of string with maxlength
526
les di,DWORD PTR [bp+4] ; Str
527
mov cx,WORD PTR [bp+8] ; length
528
mov dx,di ; Save str to calc length
529
jcxz sn_10 ; Length = 0
530
xor al,al ; Find end of string
532
repne scasb ; Find strend or length
534
dec di ; DI points at last null
536
sub ax,dx ; Ax = length
543
; Move a string with max len chars
545
; ret: pos to first null or dst+len
554
les di,DWORD PTR [bp+4] ; dst
555
lds si,DWORD PTR [bp+8] ; src
556
mov cx,WORD PTR [bp+12] ; length
557
jcxz snm_99 ; Nothing to do
558
xor al,al ; For test of end-null
561
@@: cmp al,ds:[si] ; Next char to move
563
jz snm_20 ; last char, fill with null
564
loop @B ; Continue moving
565
inc di ; Point two after last
566
snm_20: dec di ; Point at first null (or last+1)
567
snm_99: mov ax,di ; Pointer at last char
568
mov dx,es ; To-segment
580
q_stos MACRO ; as rep stosb but quicker, Uses edx
581
mov ah,al ;(2) Set up a 32 bit pattern.
584
or eax,edx ;(2) EAX has the 32 bit pattern.
586
mov edx,ecx ;(2) Save the count of bytes.
587
shr ecx,2 ;(2) Number of dwords.
590
and ecx,edx ;(2) Fill in the remaining odd bytes.
591
rep stosb ; Move last bytes if any
594
fix_es MACRO fix_cld ; Load ES if neaded
606
; Args: to,from,length
607
; Acts as one byte was moved a-time from dst to source.
616
mov edi,P-SIZEPTR[esp] ;p1
618
mov ecx,P+SIZEPTR[esp]
619
rep movsb ; Not q_movs because overlap ?
627
; Move a alligned, not overlapped, by (long) divided memory area
628
; Args: to,from,length
633
_bmove_align proc near
637
mov edi,P-SIZEPTR[esp] ;to
639
mov ecx,P+SIZEPTR[esp] ;length
640
add cx,3 ;fix if not divisible with long
650
; Move a string from higher to lower
651
; Arg from+1,to+1,length
661
mov edi,P-SIZEPTR[esp] ;p1
663
mov ecx,P+SIZEPTR[esp]
664
dec edi ; Don't move last arg
666
rep movsb ; One byte a time because overlap !
667
cld ; C compilator wants cld
675
; Append fillchars to string
676
; Args: dest,len,fill
686
mov edi,P[ebp] ; Memory pointer
687
mov ecx,P+SIZEPTR[ebp] ; Length
688
clr eax ; Find end of string
690
jnz sa_99 ; String to long, shorten it
691
movzx eax,byte ptr P+(2*SIZEPTR)[ebp] ; Fillchar
692
dec edi ; Point at end null
693
inc ecx ; rep made one dec for null-char
694
q_stos ; Store al in string
695
sa_99: mov BYTE PTR [edi],0 ; End of string
703
; Find if string contains any char in another string
705
; Ret: Pointer to first found char in str
717
mov ecx,P+SIZEPTR[ebp] ; Set
722
jz sc_fo ; Found char
723
sc_20: cmp ah,[edi] ; Test if null
724
jnz sc_10 ; Not end of set yet
725
inc esi ; Next char in str
726
sc_60: mov edi,ecx ; edi = Set
727
mov al,[esi] ; Test if this char exist
729
jnz sc_20 ; Not end of string
730
clr esi ; Return Null
731
sc_fo: mov eax,esi ; Char found here
732
mov edi,edx ; Restore
740
; Found end of string
742
; ret: Pointer to end null
750
mov edi,P-SIZEPTR[esp] ; str
751
clr eax ; Find end of string
757
mov edi,edx ; Restore
763
; Make a string with len fill-chars and endnull
764
; Args: dest,len,fill
775
mov edi,P[ebp] ; Memory pointer
776
mov ecx,P+SIZEPTR[ebp] ; Length
777
movzx eax,byte ptr P+(2*SIZEPTR)[ebp] ; Fill
779
mov BYTE PTR [edi],0 ; End NULL
780
mov eax,edi ; End i DX:AX
788
; Find a char in or end of a string
790
; Ret: pointer to found char or NullS
801
mov ah,P+SIZEPTR[ebp] ; search
802
clr al ; for scasb to find end
808
dec edi ; Not found, point at end of string
810
mov edi,edx ; Restore
817
; Test if string has a given suffix
824
mov edx,edi ; Save edi
825
mov eax,esi ; Save esi
826
mov esi,P[esp] ; get suffix
827
mov edi,P-SIZEPTR[esp] ; s1
829
mov eax,1 ; Ok and zero-test
831
jz suf_ok ; End of string; found suffix
832
cmpsb ; Compare strings
833
jz @B ; Same, possible prefix
834
xor eax,eax ; Not suffix
842
; Find a substring in string
855
mov edi,P+SIZEPTR[ebp] ; search
857
inc ecx ; ECX = search+1
858
mov ah,[edi] ; AH = First char in search
861
sf_00: mov esi,edx ; si = Current str-pos
862
sf_10: mov al,[esi] ; Test if this char exist
864
jz sf_90 ; End of string, didn't find search
867
jnz sf_10 ; Didn't find first char, continue
868
mov edx,esi ; Save str-pos in EDX
870
sf_20: cmp BYTE PTR [edi],0
871
jz sf_fo ; Found substring
874
jmps sf_00 ; Next str-pos
876
sf_90: mov edx,1 ; Return Null
877
sf_fo: mov eax,edx ; Char found here
878
dec eax ; Pointed one after
887
; Make a string of len length from another string
888
; Arg: dst,src,length
901
mov esi,P+SIZEPTR[ebp] ; src
902
mov ecx,P+SIZEPTR*2[ebp] ; Length of memory-area
903
clr al ; For test of end-null
904
jcxz sm_90 ; Nothing to move, put zero at end.
906
@@: cmp al,[esi] ; Next char to move
908
jz sm_99 ; last char, we are ready
909
loop @B ; Continue moving
910
sm_90: mov BYTE PTR [edi],al ; Set end pos
911
inc edi ; Fix that di points at end null
912
sm_99: dec edi ; di points now at end null
913
mov eax,edi ; Ret value in DX:AX
922
; Find length of string with maxlength
935
mov ecx,P+SIZEPTR[ebp] ; length
936
mov edx,edi ; Save str to calc length
937
jcxz sn_10 ; Length = 0
938
clr al ; Find end of string
939
repne scasb ; Find strend or length
941
dec edi ; DI points at last null
943
sub eax,edx ; Ax = length
951
; Move a string with max len chars
953
; ret: pos to first null or dst+len
964
mov esi,P+SIZEPTR[ebp] ; src
965
mov ecx,P+(SIZEPTR*2)[ebp] ; length
966
jcxz snm_99 ; Nothing to do
967
clr al ; For test of end-null
969
@@: cmp al,[esi] ; Next char to move
971
jz snm_20 ; last char, fill with null
972
loop @B ; Continue moving
973
inc edi ; Point two after last
974
snm_20: dec edi ; Point at first null (or last+1)
975
snm_99: mov eax,edi ; Pointer at last char
984
; Zortech has this one in standard library
990
mov ecx,esi ; Save old esi and edi
992
mov esi,P[esp] ; get source pointer (s2)
993
mov edi,P-SIZEPTR[esp] ; EDI -> s1
1001
mov esi,ecx ; Restore args