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
; Find a substring in string, return index
489
les di,DWORD PTR [bp+10] ; search
492
les di,DWORD PTR [bp+6] ; str
499
sub ax,di ; Pos from start
500
inc ax ; And first pos = 1
508
; Make a string of len length from another string
509
; Arg: dst,src,length
520
les di,DWORD PTR [bp+4] ; dst
521
lds si,DWORD PTR [bp+8] ; src
522
mov cx,WORD PTR [bp+12] ; Length of memory-area
523
xor al,al ; For test of end-null
524
jcxz sm_90 ; Nothing to move, put zero at end.
527
@@: cmp al,ds:[si] ; Next char to move
529
jz sm_99 ; last char, we are ready
530
loop @B ; Continue moving
531
sm_90: mov BYTE PTR es:[di],al ; Set end pos
532
inc di ; Fix that di points at end null
533
sm_99: dec di ; di points now at end null
534
mov ax,di ; Ret value in DX:AX
544
; Find length of string with maxlength
554
les di,DWORD PTR [bp+4] ; Str
555
mov cx,WORD PTR [bp+8] ; length
556
mov dx,di ; Save str to calc length
557
jcxz sn_10 ; Length = 0
558
xor al,al ; Find end of string
560
repne scasb ; Find strend or length
562
dec di ; DI points at last null
564
sub ax,dx ; Ax = length
571
; Move a string with max len chars
573
; ret: pos to first null or dst+len
582
les di,DWORD PTR [bp+4] ; dst
583
lds si,DWORD PTR [bp+8] ; src
584
mov cx,WORD PTR [bp+12] ; length
585
jcxz snm_99 ; Nothing to do
586
xor al,al ; For test of end-null
589
@@: cmp al,ds:[si] ; Next char to move
591
jz snm_20 ; last char, fill with null
592
loop @B ; Continue moving
593
inc di ; Point two after last
594
snm_20: dec di ; Point at first null (or last+1)
595
snm_99: mov ax,di ; Pointer at last char
596
mov dx,es ; To-segment
608
q_stos MACRO ; as rep stosb but quicker, Uses edx
609
mov ah,al ;(2) Set up a 32 bit pattern.
612
or eax,edx ;(2) EAX has the 32 bit pattern.
614
mov edx,ecx ;(2) Save the count of bytes.
615
shr ecx,2 ;(2) Number of dwords.
618
and ecx,edx ;(2) Fill in the remaining odd bytes.
619
rep stosb ; Move last bytes if any
622
fix_es MACRO fix_cld ; Load ES if neaded
634
; Args: to,from,length
635
; Acts as one byte was moved a-time from dst to source.
644
mov edi,P-SIZEPTR[esp] ;p1
646
mov ecx,P+SIZEPTR[esp]
647
rep movsb ; Not q_movs because overlap ?
655
; Move a alligned, not overlapped, by (long) divided memory area
656
; Args: to,from,length
661
_bmove_align proc near
665
mov edi,P-SIZEPTR[esp] ;to
667
mov ecx,P+SIZEPTR[esp] ;length
668
add cx,3 ;fix if not divisible with long
678
; Move a string from higher to lower
679
; Arg from+1,to+1,length
689
mov edi,P-SIZEPTR[esp] ;p1
691
mov ecx,P+SIZEPTR[esp]
692
dec edi ; Don't move last arg
694
rep movsb ; One byte a time because overlap !
695
cld ; C compilator wants cld
703
; Append fillchars to string
704
; Args: dest,len,fill
714
mov edi,P[ebp] ; Memory pointer
715
mov ecx,P+SIZEPTR[ebp] ; Length
716
clr eax ; Find end of string
718
jnz sa_99 ; String to long, shorten it
719
movzx eax,byte ptr P+(2*SIZEPTR)[ebp] ; Fillchar
720
dec edi ; Point at end null
721
inc ecx ; rep made one dec for null-char
722
q_stos ; Store al in string
723
sa_99: mov BYTE PTR [edi],0 ; End of string
731
; Find if string contains any char in another string
733
; Ret: Pointer to first found char in str
745
mov ecx,P+SIZEPTR[ebp] ; Set
750
jz sc_fo ; Found char
751
sc_20: cmp ah,[edi] ; Test if null
752
jnz sc_10 ; Not end of set yet
753
inc esi ; Next char in str
754
sc_60: mov edi,ecx ; edi = Set
755
mov al,[esi] ; Test if this char exist
757
jnz sc_20 ; Not end of string
758
clr esi ; Return Null
759
sc_fo: mov eax,esi ; Char found here
760
mov edi,edx ; Restore
768
; Found end of string
770
; ret: Pointer to end null
778
mov edi,P-SIZEPTR[esp] ; str
779
clr eax ; Find end of string
785
mov edi,edx ; Restore
791
; Make a string with len fill-chars and endnull
792
; Args: dest,len,fill
803
mov edi,P[ebp] ; Memory pointer
804
mov ecx,P+SIZEPTR[ebp] ; Length
805
movzx eax,byte ptr P+(2*SIZEPTR)[ebp] ; Fill
807
mov BYTE PTR [edi],0 ; End NULL
808
mov eax,edi ; End i DX:AX
816
; Find a char in or end of a string
818
; Ret: pointer to found char or NullS
829
mov ah,P+SIZEPTR[ebp] ; search
830
clr al ; for scasb to find end
836
dec edi ; Not found, point at end of string
838
mov edi,edx ; Restore
845
; Test if string has a given suffix
852
mov edx,edi ; Save edi
853
mov eax,esi ; Save esi
854
mov esi,P[esp] ; get suffix
855
mov edi,P-SIZEPTR[esp] ; s1
857
mov eax,1 ; Ok and zero-test
859
jz suf_ok ; End of string; found suffix
860
cmpsb ; Compare strings
861
jz @B ; Same, possible prefix
862
xor eax,eax ; Not suffix
870
; Find a substring in string
883
mov edi,P+SIZEPTR[ebp] ; search
885
inc ecx ; ECX = search+1
886
mov ah,[edi] ; AH = First char in search
889
sf_00: mov esi,edx ; si = Current str-pos
890
sf_10: mov al,[esi] ; Test if this char exist
892
jz sf_90 ; End of string, didn't find search
895
jnz sf_10 ; Didn't find first char, continue
896
mov edx,esi ; Save str-pos in EDX
898
sf_20: cmp BYTE PTR [edi],0
899
jz sf_fo ; Found substring
902
jmps sf_00 ; Next str-pos
904
sf_90: mov edx,1 ; Return Null
905
sf_fo: mov eax,edx ; Char found here
906
dec eax ; Pointed one after
915
; Find a substring in string, return index
924
push P+SIZEPTR[ebp] ; search
929
jz si_99 ; Not found, return NULL
930
sub eax,P[ebp] ; Pos from start
931
inc eax ; And first pos = 1
938
; Make a string of len length from another string
939
; Arg: dst,src,length
952
mov esi,P+SIZEPTR[ebp] ; src
953
mov ecx,P+SIZEPTR*2[ebp] ; Length of memory-area
954
clr al ; For test of end-null
955
jcxz sm_90 ; Nothing to move, put zero at end.
957
@@: cmp al,[esi] ; Next char to move
959
jz sm_99 ; last char, we are ready
960
loop @B ; Continue moving
961
sm_90: mov BYTE PTR [edi],al ; Set end pos
962
inc edi ; Fix that di points at end null
963
sm_99: dec edi ; di points now at end null
964
mov eax,edi ; Ret value in DX:AX
973
; Find length of string with maxlength
986
mov ecx,P+SIZEPTR[ebp] ; length
987
mov edx,edi ; Save str to calc length
988
jcxz sn_10 ; Length = 0
989
clr al ; Find end of string
990
repne scasb ; Find strend or length
992
dec edi ; DI points at last null
994
sub eax,edx ; Ax = length
1002
; Move a string with max len chars
1004
; ret: pos to first null or dst+len
1014
mov edi,P[ebp] ; dst
1015
mov esi,P+SIZEPTR[ebp] ; src
1016
mov ecx,P+(SIZEPTR*2)[ebp] ; length
1017
jcxz snm_99 ; Nothing to do
1018
clr al ; For test of end-null
1020
@@: cmp al,[esi] ; Next char to move
1022
jz snm_20 ; last char, fill with null
1023
loop @B ; Continue moving
1024
inc edi ; Point two after last
1025
snm_20: dec edi ; Point at first null (or last+1)
1026
snm_99: mov eax,edi ; Pointer at last char
1035
; Zortech has this one in standard library
1041
mov ecx,esi ; Save old esi and edi
1043
mov esi,P[esp] ; get source pointer (s2)
1044
mov edi,P-SIZEPTR[esp] ; EDI -> s1
1052
mov esi,ecx ; Restore args