mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
b388eb004d
bmove_allign -> bmove_align Added OLAP function ROLLUP Split mysql_fix_privilege_tables to a script and a .sql data file Added new (MEMROOT*) functions to avoid calling current_thd() when creating some common objects. Added table_alias_charset, for easier --lower-case-table-name handling Better SQL_MODE handling (Setting complex options also sets sub options) New (faster) assembler string functions for x86 BitKeeper/etc/ignore: added libmysqld/sql_state.c client/mysql.cc: Added SQLSTATE to error messages Added new function put_error() to be able to clean up some old code. client/mysqltest.c: Write ERROR SQLSTATE for all errors dbug/dbug.c: Portability fixes include/m_string.h: Rename bmove_allign as bmove_align include/mysql.h: Added SQLSTATE (for embedded version) include/mysql_com.h: Send correct SQLSTATE for the error to the client libmysql/libmysql.c: Changed default error state to HY000 Applied code cleanup patch libmysqld/Makefile.am: Added sql_state.cc libmysqld/libmysqld.c: Added sqlstate mysql-test/r/analyse.result: Updated results mysql-test/r/ansi.result: Updated results mysql-test/r/auto_increment.result: Updated results mysql-test/r/bdb-deadlock.result: Updated results mysql-test/r/bdb.result: Updated results mysql-test/r/comments.result: Updated results mysql-test/r/create.result: Updated results mysql-test/r/ctype_collate.result: Updated results mysql-test/r/delayed.result: Updated results mysql-test/r/delete.result: Updated results mysql-test/r/derived.result: Updated results mysql-test/r/distinct.result: Updated results mysql-test/r/drop.result: Updated results mysql-test/r/err000001.result: Updated results mysql-test/r/explain.result: Updated results mysql-test/r/flush.result: Updated results mysql-test/r/fulltext.result: Updated results mysql-test/r/func_gconcat.result: Updated results mysql-test/r/func_system.result: Updated results mysql-test/r/grant_cache.result: Updated results mysql-test/r/group_by.result: Updated results mysql-test/r/handler.result: Updated results mysql-test/r/heap.result: Updated results mysql-test/r/heap_btree.result: Updated results mysql-test/r/heap_hash.result: Updated results mysql-test/r/innodb.result: Updated results mysql-test/r/innodb_handler.result: Updated results mysql-test/r/insert_select.result: Updated results mysql-test/r/insert_update.result: Updated results mysql-test/r/join.result: Updated results mysql-test/r/join_outer.result: Updated results mysql-test/r/key.result: Updated results mysql-test/r/lock.result: Updated results mysql-test/r/lock_multi.result: Updated results mysql-test/r/merge.result: Updated results mysql-test/r/multi_update.result: Updated results mysql-test/r/myisam.result: Updated results mysql-test/r/null.result: Updated results mysql-test/r/olap.result: Updated results mysql-test/r/order_by.result: Updated results mysql-test/r/packet.result: Updated results mysql-test/r/query_cache.result: Updated results mysql-test/r/row.result: Updated results mysql-test/r/rpl000001.result: Updated results mysql-test/r/rpl000009.result: Updated results mysql-test/r/rpl_empty_master_crash.result: Updated results mysql-test/r/rpl_log.result: Updated results mysql-test/r/rpl_replicate_do.result: Updated results mysql-test/r/rpl_rotate_logs.result: Updated results mysql-test/r/select.result: Updated results mysql-test/r/select_safe.result: Updated results mysql-test/r/show_check.result: Updated results mysql-test/r/sql_mode.result: Updated results mysql-test/r/subselect.result: Updated results mysql-test/r/temp_table.result: Updated results mysql-test/r/truncate.result: Updated results mysql-test/r/type_blob.result: Updated results mysql-test/r/type_decimal.result: Updated results mysql-test/r/type_float.result: Updated results mysql-test/r/type_ranges.result: Updated results mysql-test/r/union.result: Updated results mysql-test/r/update.result: Updated results mysql-test/r/user_var.result: Updated results mysql-test/r/varbinary.result: Updated results mysql-test/r/variables.result: Updated results mysql-test/t/ansi.test: Test of sql_mode mysql-test/t/derived.test: Updated results mysql-test/t/func_system.test: Make this independen of the MySQL server name mysql-test/t/lowercase_table.test: Cleanup mysql-test/t/olap.test: A lot of new tests mysql-test/t/sql_mode.test: More test for sql_mode mysql-test/t/subselect.test: Added a few new tests (to find a bug in the item_ref code) scripts/Makefile.am: Added mysql_fix_privilege_tables.sql scripts/mysql_fix_privilege_tables.sh: Totally new script. This bascily just pipes mysql_fix_privilege_tables.sql through 'mysql' to 'mysqld' sql/Makefile.am: Added sql_state.cc sql/item.cc: Extended Item_field::eq() to be able to better match GROUP BY fields on the command line. Needed for ROLLUP sql/item.h: Added function to be able to avoid calling current_thd() when doing new Item. sql/item_sum.cc: Moved copy_or_same() and some reset() functions from item_sum.h Needed to be able to access thd->mem_root. sql/item_sum.h: Moved some functions to item_sum.cc Added make_unique() for ROLLUP sql/item_uniq.h: Fixed return value sql/mysql_priv.h: Updated MODE flags sql/mysqld.cc: Added ANSI as it's own mode Moved charset_info variables here Cleaned up handler_count handling (for NT) Added table_alias_charset, for easier --lower-case-table-name handling sql/net_serv.cc: New comment sql/protocol.cc: Send SQLSTATE to client sql/set_var.cc: Better SQL_MODE handling (Setting complex options also sets sub options) sql/set_var.h: Better SQL_MODE handling sql/sql_base.cc: Make alias depend on --lower-case-table-names Make find_item_in_list also check database name sql/sql_cache.cc: Indentation cleanup sql/sql_list.h: Added safety assert Addes support of alloc without current_thd() sql/sql_prepare.cc: Update after prototype change sql/sql_select.cc: Added ROLLUP sql/sql_select.h: structures for rollup sql/sql_show.cc: Easier SQL_MODE handling sql/sql_string.cc: Move CHARSET_INFO to mysqld (to be together with all other global variables) sql/sql_string.h: Added function to be able to avoid calling current_thd() when doing new Item. sql/sql_table.cc: Simpler --lower-case-table-name handling sql/sql_union.cc: Update after prototype change sql/sql_yacc.yy: ROLLUP sql/unireg.h: bmove_allign ->bmove_align strings/Makefile.am: Fix to be able to compile str_test.c strings/ctype.c: Removed empty lines strings/str_test.c: Added test of bmove_align strings/strings-x86.s: Faster bmove_align, bmove_upp and strmake strings/strings.asm: move_allg
1060 lines
19 KiB
NASM
1060 lines
19 KiB
NASM
; Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
|
;
|
|
; This 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.
|
|
;
|
|
; This 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 this library; if not, write to the Free
|
|
; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
; MA 02111-1307, USA
|
|
|
|
; Note that if you don't have a macro assembler (like MASM) to compile
|
|
; this file, you can instead compile all *.c files in the string
|
|
; directory.
|
|
|
|
TITLE Stringfunctions that we use often at MSDOS / Intel 8086
|
|
|
|
ifndef M_I386
|
|
.8087
|
|
DOSSEG
|
|
.MODEL LARGE
|
|
.CODE
|
|
|
|
;
|
|
; Some macros
|
|
;
|
|
|
|
q_movs MACRO ; as rep movsb but quicker
|
|
shr cx,1
|
|
rep movsw ; Move 2 bytes at a time
|
|
adc cx,cx
|
|
rep movsb ; Move last byte if any
|
|
ENDM
|
|
|
|
q_stos MACRO ; as rep stosb but quicker
|
|
mov ah,al ; For word store
|
|
shr cx,1
|
|
rep stosw ; Move 2 bytes at a time
|
|
adc cx,cx
|
|
rep stosb ; Move last byte if any
|
|
ENDM
|
|
|
|
ifndef ZTC ; If not using ZORTECH compiler
|
|
;
|
|
; Compare memory
|
|
; Args: s1,s2,length
|
|
;
|
|
|
|
PUBLIC _bcmp
|
|
_bcmp PROC
|
|
mov bx,bp ; Save bp
|
|
mov dx,di ; Save di
|
|
mov bp,sp
|
|
push ds
|
|
push si
|
|
les di,DWORD PTR [bp+8] ; s2
|
|
lds si,DWORD PTR [bp+4] ; s1
|
|
mov cx,WORD PTR [bp+12] ; Length of memory-area
|
|
jcxz @F ; Length = 0, return same
|
|
; cld ; Work uppward
|
|
repe cmpsb ; Compare strings
|
|
jz @F ; Match found
|
|
inc cx ; return matchpoint +1
|
|
@@: mov ax,cx ; Return 0 if match, else pos from end
|
|
pop si
|
|
pop ds
|
|
mov di,dx
|
|
mov bp,bx
|
|
ret
|
|
_bcmp ENDP
|
|
|
|
;
|
|
; Find a char in a string
|
|
; Arg: str,char
|
|
; Ret: pointer to found char or NullS
|
|
;
|
|
|
|
ifdef better_stringfunctions ; Breaks window linkage (broken linking)
|
|
|
|
PUBLIC _strchr
|
|
_strchr PROC
|
|
mov bx,bp ; Save bp and di
|
|
mov dx,di
|
|
mov bp,sp
|
|
les di,DWORD PTR [bp+4] ; str
|
|
mov ah,BYTE PTR [bp+8] ; search
|
|
xor al,al ; for scasb to find end
|
|
|
|
@@: cmp ah,es:[di]
|
|
jz @F ; Found char
|
|
scasb
|
|
jnz @B ; Not end
|
|
xor di,di ; Not found
|
|
mov es,di
|
|
@@: mov ax,di
|
|
mov di,dx ; Restore
|
|
mov dx,es ; Seg adr
|
|
mov bp,bx ; Restore
|
|
ret
|
|
_strchr ENDP
|
|
|
|
;
|
|
; Find length of string
|
|
; arg: str
|
|
; ret: length
|
|
;
|
|
|
|
PUBLIC _strlen
|
|
_strlen PROC
|
|
mov bx,sp
|
|
mov dx,di
|
|
les di,DWORD PTR ss:[bx+4] ; Str
|
|
xor al,al ; Find end of string
|
|
mov cx,-1
|
|
; cld
|
|
repne scasb ; Find strend or length
|
|
inc cx ; Calc strlength
|
|
not cx
|
|
mov ax,cx
|
|
mov di,dx ; Restore register
|
|
ret
|
|
_strlen ENDP
|
|
|
|
endif
|
|
|
|
;
|
|
; Move a string
|
|
; arg: dst,src
|
|
; ret: end-null of to
|
|
;
|
|
|
|
PUBLIC _strmov
|
|
_strmov PROC
|
|
mov bx,bp
|
|
mov cx,si
|
|
mov bp,sp
|
|
push ds
|
|
push di
|
|
les di,DWORD PTR [bp+4] ; dst
|
|
lds si,DWORD PTR [bp+8] ; src
|
|
; cld
|
|
@@: mov al,ds:[si]
|
|
movsb ; move arg
|
|
and al,al
|
|
jnz @B ; Not last
|
|
lea ax,WORD PTR [di-1] ; Set DX:AX to point at last null
|
|
mov dx,es
|
|
pop di
|
|
pop ds
|
|
mov si,cx
|
|
mov bp,bx
|
|
ret
|
|
_strmov ENDP
|
|
|
|
;
|
|
; Fill a area of memory with a walue
|
|
; Args: to,length,fillchar
|
|
;
|
|
|
|
PUBLIC _bfill
|
|
_bfill PROC
|
|
mov bx,sp ; Get args through BX
|
|
mov al,BYTE PTR ss:[bx+10] ; Fill
|
|
bfill_10:
|
|
mov dx,di ; Save di
|
|
les di,DWORD PTR ss:[bx+4] ; Memory pointer
|
|
mov cx,WORD PTR ss:[bx+8] ; Length
|
|
; cld
|
|
q_stos
|
|
mov di,dx
|
|
ret
|
|
_bfill ENDP
|
|
|
|
;
|
|
; Fill a area with null
|
|
; Args: to,length
|
|
|
|
PUBLIC _bzero
|
|
_bzero PROC
|
|
mov bx,sp ; Get args through BX
|
|
mov al,0 ; Fill with null
|
|
jmp short bfill_10
|
|
_bzero ENDP
|
|
|
|
endif ; ZTC
|
|
|
|
;
|
|
; Move a memory area
|
|
; Args: to,from,length
|
|
;
|
|
|
|
PUBLIC _bmove
|
|
_bmove PROC
|
|
mov bx,bp
|
|
mov dx,di
|
|
mov ax,si
|
|
mov bp,sp
|
|
push ds
|
|
lds si,DWORD PTR [bp+8] ; from
|
|
les di,DWORD PTR [bp+4] ; to
|
|
mov cx,WORD PTR [bp+12] ; Length of memory-area
|
|
; cld ; Work uppward
|
|
rep movsb ; Not q_movs because overlap ?
|
|
pop ds
|
|
mov si,ax
|
|
mov di,dx
|
|
mov bp,bx
|
|
ret
|
|
_bmove ENDP
|
|
|
|
;
|
|
; Move a alligned, not overlapped, by (long) divided memory area
|
|
; Args: to,from,length
|
|
;
|
|
|
|
PUBLIC _bmove_align
|
|
_bmove_align PROC
|
|
mov bx,bp
|
|
mov dx,di
|
|
mov ax,si
|
|
mov bp,sp
|
|
push ds
|
|
lds si,DWORD PTR [bp+8] ; from
|
|
les di,DWORD PTR [bp+4] ; to
|
|
mov cx,WORD PTR [bp+12] ; Length of memory-area
|
|
; cld ; Work uppward
|
|
inc cx ; fix if not divisible with word
|
|
shr cx,1
|
|
rep movsw ; Move 2 bytes at a time
|
|
pop ds
|
|
mov si,ax
|
|
mov di,dx
|
|
mov bp,bx
|
|
ret
|
|
_bmove_align ENDP
|
|
|
|
;
|
|
; Move a string from higher to lower
|
|
; Arg from+1,to+1,length
|
|
;
|
|
|
|
PUBLIC _bmove_upp
|
|
_bmove_upp PROC
|
|
mov bx,bp
|
|
mov dx,di
|
|
mov ax,si
|
|
mov bp,sp
|
|
push ds
|
|
lds si,DWORD PTR [bp+8] ; from
|
|
les di,DWORD PTR [bp+4] ; to
|
|
mov cx,WORD PTR [bp+12] ; Length of memory-area
|
|
dec di ; Don't move last arg
|
|
dec si
|
|
std ; Work downward
|
|
rep movsb ; Not q_movs because overlap ?
|
|
cld ; C compilator want cld
|
|
pop ds
|
|
mov si,ax
|
|
mov di,dx
|
|
mov bp,bx
|
|
ret
|
|
_bmove_upp ENDP
|
|
|
|
;
|
|
; Append fillchars to string
|
|
; Args: dest,len,fill
|
|
;
|
|
|
|
PUBLIC _strappend
|
|
_strappend PROC
|
|
mov bx,bp
|
|
mov dx,di
|
|
mov bp,sp
|
|
les di,DWORD PTR [bp+4] ; Memory pointer
|
|
mov cx,WORD PTR [bp+8] ; Length
|
|
sub al,al ; Find end of string
|
|
; cld
|
|
repne scasb
|
|
jnz sa_99 ; String to long, shorten it
|
|
mov al,BYTE PTR [bp+10] ; Fillchar
|
|
dec di ; Point at end null
|
|
inc cx ; rep made one dec for null-char
|
|
q_stos ; Store al in string
|
|
sa_99: mov BYTE PTR es:[di],0 ; End of string
|
|
mov di,dx
|
|
mov bp,bx
|
|
ret
|
|
_strappend ENDP
|
|
|
|
;
|
|
; Find if string contains any char in another string
|
|
; Arg: str,set
|
|
; Ret: Pointer to first found char in str
|
|
;
|
|
|
|
PUBLIC _strcont
|
|
_strcont PROC
|
|
mov bx,bp ; Save bp and di in regs
|
|
mov dx,di
|
|
mov bp,sp
|
|
push ds
|
|
push si
|
|
lds si,DWORD PTR [bp+4] ; str
|
|
les di,DWORD PTR [bp+8] ; Set
|
|
mov cx,di ; Save for loop
|
|
xor ah,ah ; For endtest
|
|
jmp sc_60
|
|
|
|
sc_10: scasb
|
|
jz sc_fo ; Found char
|
|
sc_20: cmp ah,es:[di] ; Test if null
|
|
jnz sc_10 ; Not end of set yet
|
|
inc si ; Next char in str
|
|
mov di,cx ; es:di = Set
|
|
sc_60: mov al,ds:[si] ; Test if this char exist
|
|
and al,al
|
|
jnz sc_20 ; Not end of string
|
|
sub si,si ; Return Null
|
|
mov ds,si
|
|
sc_fo: mov ax,si ; Char found here
|
|
mov di,dx ; Restore
|
|
mov dx,ds ; Seg of found char
|
|
pop si
|
|
pop ds
|
|
mov bp,bx
|
|
ret
|
|
_strcont ENDP
|
|
|
|
;
|
|
; Found end of string
|
|
; Arg: str
|
|
; ret: Pointer to end null
|
|
;
|
|
|
|
PUBLIC _strend
|
|
_strend PROC
|
|
mov bx,sp
|
|
mov dx,di ; Save
|
|
les di,DWORD PTR ss:[bx+4] ; str
|
|
mov cx,-1
|
|
sub al,al ; Find end of string
|
|
; cld
|
|
repne scasb
|
|
lea ax,WORD PTR [di-1] ; Endpos i DX:AX
|
|
mov di,dx ; Restore
|
|
mov dx,es
|
|
ret
|
|
_strend ENDP
|
|
|
|
;
|
|
; Make a string with len fill-chars and endnull
|
|
; Args: dest,len,fill
|
|
; Ret: dest+len
|
|
;
|
|
|
|
PUBLIC _strfill
|
|
_strfill PROC
|
|
mov bx,bp ; Save sp
|
|
mov bp,sp
|
|
push di
|
|
les di,DWORD PTR [bp+4] ; Memory pointer
|
|
mov cx,WORD PTR [bp+8] ; Length
|
|
mov al,BYTE PTR [bp+10] ; Fill
|
|
; cld
|
|
q_stos
|
|
mov BYTE PTR es:[di],0 ; End NULL
|
|
mov ax,di ; End i DX:AX
|
|
mov dx,es
|
|
pop di
|
|
mov bp,bx
|
|
ret
|
|
_strfill ENDP
|
|
|
|
;
|
|
; Find a char in or end of a string
|
|
; Arg: str,char
|
|
; Ret: pointer to found char or NullS
|
|
;
|
|
|
|
PUBLIC _strcend
|
|
_strcend PROC
|
|
mov bx,bp ; Save bp and di
|
|
mov dx,di
|
|
mov bp,sp
|
|
les di,DWORD PTR [bp+4] ; str
|
|
mov ah,BYTE PTR [bp+8] ; search
|
|
xor al,al ; for scasb to find end
|
|
|
|
@@: cmp ah,es:[di]
|
|
jz @F ; Found char
|
|
scasb
|
|
jnz @B ; Not end
|
|
dec di ; Not found, point at end of string
|
|
@@: mov ax,di
|
|
mov di,dx ; Restore
|
|
mov dx,es ; Seg adr
|
|
mov bp,bx ; Restore
|
|
ret
|
|
_strcend ENDP
|
|
|
|
;
|
|
; Test if string has a given suffix
|
|
;
|
|
|
|
PUBLIC _is_prefix
|
|
_is_prefix PROC
|
|
mov dx,di ; Save di
|
|
mov bx,sp ; Arguments through bx
|
|
push ds
|
|
push si
|
|
les di,DWORD PTR ss:[bx+8] ; s2
|
|
lds si,DWORD PTR ss:[bx+4] ; s1
|
|
mov ax,1 ; Ok and zero-test
|
|
; cld ; Work uppward
|
|
@@: cmp ah,es:[di]
|
|
jz suf_ok ; End of string; found suffix
|
|
cmpsb ; Compare strings
|
|
jz @B ; Same, possible prefix
|
|
xor ax,ax ; Not suffix
|
|
suf_ok: pop si
|
|
pop ds
|
|
mov di,dx
|
|
ret
|
|
_is_prefix ENDP
|
|
|
|
;
|
|
; Find a substring in string
|
|
; Arg: str,search
|
|
;
|
|
|
|
PUBLIC _strstr
|
|
_strstr PROC
|
|
mov bx,bp
|
|
mov bp,sp
|
|
push ds
|
|
push di
|
|
push si
|
|
lds si,DWORD PTR [bp+4] ; str
|
|
les di,DWORD PTR [bp+8] ; search
|
|
mov cx,di
|
|
inc cx ; CX = search+1
|
|
mov ah,es:[di] ; AH = First char in search
|
|
jmp sf_10
|
|
|
|
sf_00: mov si,dx ; si = Current str-pos
|
|
sf_10: mov al,ds:[si] ; Test if this char exist
|
|
and al,al
|
|
jz sf_90 ; End of string, didn't find search
|
|
inc si
|
|
cmp al,ah
|
|
jnz sf_10 ; Didn't find first char, continue
|
|
mov dx,si ; Save str-pos in DX
|
|
mov di,cx
|
|
sf_20: cmp BYTE PTR es:[di],0
|
|
jz sf_fo ; Found substring
|
|
cmpsb
|
|
jz sf_20 ; Char ok
|
|
jmp sf_00 ; Next str-pos
|
|
|
|
sf_90: sub dx,dx ; Return Null
|
|
mov ds,dx
|
|
inc dx ; Because of following dec
|
|
sf_fo: mov ax,dx ; Char found here
|
|
dec ax ; Pointed one after
|
|
mov dx,ds
|
|
pop si
|
|
pop di ; End
|
|
pop ds
|
|
mov bp,bx
|
|
ret
|
|
_strstr ENDP
|
|
|
|
;
|
|
; Find a substring in string, return index
|
|
; Arg: str,search
|
|
;
|
|
|
|
PUBLIC _strinstr
|
|
_strinstr PROC
|
|
push bp
|
|
mov bp,sp
|
|
push di
|
|
les di,DWORD PTR [bp+10] ; search
|
|
push es
|
|
push di
|
|
les di,DWORD PTR [bp+6] ; str
|
|
push es
|
|
push di
|
|
call _strstr
|
|
mov cx,ax
|
|
or cx,dx
|
|
jz si_99
|
|
sub ax,di ; Pos from start
|
|
inc ax ; And first pos = 1
|
|
si_99: add sp,8
|
|
pop di
|
|
pop bp
|
|
ret
|
|
_strinstr ENDP
|
|
|
|
;
|
|
; Make a string of len length from another string
|
|
; Arg: dst,src,length
|
|
; ret: end of dst
|
|
;
|
|
|
|
PUBLIC _strmake
|
|
_strmake PROC
|
|
mov bx,bp
|
|
mov bp,sp
|
|
push ds
|
|
push di
|
|
push si
|
|
les di,DWORD PTR [bp+4] ; dst
|
|
lds si,DWORD PTR [bp+8] ; src
|
|
mov cx,WORD PTR [bp+12] ; Length of memory-area
|
|
xor al,al ; For test of end-null
|
|
jcxz sm_90 ; Nothing to move, put zero at end.
|
|
; cld ; Work uppward
|
|
|
|
@@: cmp al,ds:[si] ; Next char to move
|
|
movsb ; move arg
|
|
jz sm_99 ; last char, we are ready
|
|
loop @B ; Continue moving
|
|
sm_90: mov BYTE PTR es:[di],al ; Set end pos
|
|
inc di ; Fix that di points at end null
|
|
sm_99: dec di ; di points now at end null
|
|
mov ax,di ; Ret value in DX:AX
|
|
mov dx,es
|
|
pop si
|
|
pop di
|
|
pop ds
|
|
mov bp,bx
|
|
ret
|
|
_strmake ENDP
|
|
|
|
;
|
|
; Find length of string with maxlength
|
|
; arg: str,maxlength
|
|
; ret: length
|
|
;
|
|
|
|
PUBLIC _strnlen
|
|
_strnlen PROC
|
|
mov bx,bp
|
|
mov bp,sp
|
|
push di
|
|
les di,DWORD PTR [bp+4] ; Str
|
|
mov cx,WORD PTR [bp+8] ; length
|
|
mov dx,di ; Save str to calc length
|
|
jcxz sn_10 ; Length = 0
|
|
xor al,al ; Find end of string
|
|
; cld
|
|
repne scasb ; Find strend or length
|
|
jnz sn_10
|
|
dec di ; DI points at last null
|
|
sn_10: mov ax,di
|
|
sub ax,dx ; Ax = length
|
|
pop di
|
|
mov bp,bx
|
|
ret
|
|
_strnlen ENDP
|
|
|
|
;
|
|
; Move a string with max len chars
|
|
; arg: dst,src,len
|
|
; ret: pos to first null or dst+len
|
|
|
|
PUBLIC _strnmov
|
|
_strnmov PROC
|
|
mov bx,bp
|
|
mov bp,sp
|
|
push ds
|
|
push di
|
|
push si
|
|
les di,DWORD PTR [bp+4] ; dst
|
|
lds si,DWORD PTR [bp+8] ; src
|
|
mov cx,WORD PTR [bp+12] ; length
|
|
jcxz snm_99 ; Nothing to do
|
|
xor al,al ; For test of end-null
|
|
; cld
|
|
|
|
@@: cmp al,ds:[si] ; Next char to move
|
|
movsb ; move arg
|
|
jz snm_20 ; last char, fill with null
|
|
loop @B ; Continue moving
|
|
inc di ; Point two after last
|
|
snm_20: dec di ; Point at first null (or last+1)
|
|
snm_99: mov ax,di ; Pointer at last char
|
|
mov dx,es ; To-segment
|
|
pop si
|
|
pop di
|
|
pop ds
|
|
mov bp,bx ; Restore
|
|
ret
|
|
_strnmov ENDP
|
|
|
|
else ; M_I386
|
|
|
|
include macros.asm
|
|
|
|
q_stos MACRO ; as rep stosb but quicker, Uses edx
|
|
mov ah,al ;(2) Set up a 32 bit pattern.
|
|
mov edx,eax ;(2)
|
|
shl edx,16 ;(3)
|
|
or eax,edx ;(2) EAX has the 32 bit pattern.
|
|
|
|
mov edx,ecx ;(2) Save the count of bytes.
|
|
shr ecx,2 ;(2) Number of dwords.
|
|
rep stosd ;(5 + 5n)
|
|
mov cl,3 ;(2)
|
|
and ecx,edx ;(2) Fill in the remaining odd bytes.
|
|
rep stosb ; Move last bytes if any
|
|
ENDM
|
|
|
|
fix_es MACRO fix_cld ; Load ES if neaded
|
|
ife ESeqDS
|
|
mov ax,ds
|
|
mov es,ax
|
|
endif
|
|
ifnb <fix_cld>
|
|
cld
|
|
endif
|
|
ENDM
|
|
|
|
;
|
|
; Move a memory area
|
|
; Args: to,from,length
|
|
; Acts as one byte was moved a-time from dst to source.
|
|
;
|
|
|
|
begcode bmove
|
|
public _bmove
|
|
_bmove proc near
|
|
fix_es 1
|
|
mov edx,edi
|
|
mov eax,esi
|
|
mov edi,P-SIZEPTR[esp] ;p1
|
|
mov esi,P[esp] ;p2
|
|
mov ecx,P+SIZEPTR[esp]
|
|
rep movsb ; Not q_movs because overlap ?
|
|
mov esi,eax
|
|
mov edi,edx
|
|
ret
|
|
_bmove ENDP
|
|
endcode bmove
|
|
|
|
;
|
|
; Move a alligned, not overlapped, by (long) divided memory area
|
|
; Args: to,from,length
|
|
;
|
|
|
|
begcode bmove_align
|
|
public _bmove_align
|
|
_bmove_align proc near
|
|
fix_es 1
|
|
mov edx,edi
|
|
mov eax,esi
|
|
mov edi,P-SIZEPTR[esp] ;to
|
|
mov esi,P[esp] ;from
|
|
mov ecx,P+SIZEPTR[esp] ;length
|
|
add cx,3 ;fix if not divisible with long
|
|
shr cx,2
|
|
rep movsd
|
|
mov esi,eax
|
|
mov edi,edx
|
|
ret
|
|
_bmove_align ENDP
|
|
endcode bmove_align
|
|
|
|
;
|
|
; Move a string from higher to lower
|
|
; Arg from+1,to+1,length
|
|
;
|
|
|
|
begcode bmove_upp
|
|
public _bmove_upp
|
|
_bmove_upp proc near
|
|
fix_es
|
|
std ; Work downward
|
|
mov edx,edi
|
|
mov eax,esi
|
|
mov edi,P-SIZEPTR[esp] ;p1
|
|
mov esi,P[esp] ;p2
|
|
mov ecx,P+SIZEPTR[esp]
|
|
dec edi ; Don't move last arg
|
|
dec esi
|
|
rep movsb ; One byte a time because overlap !
|
|
cld ; C compilator wants cld
|
|
mov esi,eax
|
|
mov edi,edx
|
|
ret
|
|
_bmove_upp ENDP
|
|
endcode bmove_upp
|
|
|
|
;
|
|
; Append fillchars to string
|
|
; Args: dest,len,fill
|
|
;
|
|
|
|
begcode strappend
|
|
public _strappend
|
|
_strappend proc near
|
|
push ebp
|
|
mov ebp,esp
|
|
fix_es 1
|
|
push edi
|
|
mov edi,P[ebp] ; Memory pointer
|
|
mov ecx,P+SIZEPTR[ebp] ; Length
|
|
clr eax ; Find end of string
|
|
repne scasb
|
|
jnz sa_99 ; String to long, shorten it
|
|
movzx eax,byte ptr P+(2*SIZEPTR)[ebp] ; Fillchar
|
|
dec edi ; Point at end null
|
|
inc ecx ; rep made one dec for null-char
|
|
q_stos ; Store al in string
|
|
sa_99: mov BYTE PTR [edi],0 ; End of string
|
|
pop edi
|
|
pop ebp
|
|
ret
|
|
_strappend ENDP
|
|
endcode strappend
|
|
|
|
;
|
|
; Find if string contains any char in another string
|
|
; Arg: str,set
|
|
; Ret: Pointer to first found char in str
|
|
;
|
|
|
|
begcode strcont
|
|
PUBLIC _strcont
|
|
_strcont proc near
|
|
push ebp
|
|
mov ebp,esp
|
|
fix_es 1
|
|
mov edx,edi
|
|
push esi
|
|
mov esi,P[ebp] ; str
|
|
mov ecx,P+SIZEPTR[ebp] ; Set
|
|
clr ah ; For endtest
|
|
jmps sc_60
|
|
|
|
sc_10: scasb
|
|
jz sc_fo ; Found char
|
|
sc_20: cmp ah,[edi] ; Test if null
|
|
jnz sc_10 ; Not end of set yet
|
|
inc esi ; Next char in str
|
|
sc_60: mov edi,ecx ; edi = Set
|
|
mov al,[esi] ; Test if this char exist
|
|
and al,al
|
|
jnz sc_20 ; Not end of string
|
|
clr esi ; Return Null
|
|
sc_fo: mov eax,esi ; Char found here
|
|
mov edi,edx ; Restore
|
|
pop esi
|
|
pop ebp
|
|
ret
|
|
_strcont ENDP
|
|
endcode strcont
|
|
|
|
;
|
|
; Found end of string
|
|
; Arg: str
|
|
; ret: Pointer to end null
|
|
;
|
|
|
|
begcode strend
|
|
public _strend
|
|
_strend proc near
|
|
fix_es 1
|
|
mov edx,edi ; Save
|
|
mov edi,P-SIZEPTR[esp] ; str
|
|
clr eax ; Find end of string
|
|
mov ecx,eax
|
|
dec ecx ; ECX = -1
|
|
repne scasb
|
|
mov eax,edi
|
|
dec eax
|
|
mov edi,edx ; Restore
|
|
ret
|
|
_strend endp
|
|
endcode strend
|
|
|
|
;
|
|
; Make a string with len fill-chars and endnull
|
|
; Args: dest,len,fill
|
|
; Ret: dest+len
|
|
;
|
|
|
|
begcode strfill
|
|
public _strfill
|
|
_strfill proc near
|
|
push ebp
|
|
mov ebp,esp
|
|
fix_es 1
|
|
push edi
|
|
mov edi,P[ebp] ; Memory pointer
|
|
mov ecx,P+SIZEPTR[ebp] ; Length
|
|
movzx eax,byte ptr P+(2*SIZEPTR)[ebp] ; Fill
|
|
q_stos
|
|
mov BYTE PTR [edi],0 ; End NULL
|
|
mov eax,edi ; End i DX:AX
|
|
pop edi
|
|
pop ebp
|
|
ret
|
|
_strfill endp
|
|
endcode strfill
|
|
|
|
;
|
|
; Find a char in or end of a string
|
|
; Arg: str,char
|
|
; Ret: pointer to found char or NullS
|
|
;
|
|
|
|
begcode strcend
|
|
public _strcend
|
|
_strcend proc near
|
|
push ebp
|
|
mov ebp,esp
|
|
fix_es 1
|
|
mov edx,edi
|
|
mov edi,P[ebp] ; str
|
|
mov ah,P+SIZEPTR[ebp] ; search
|
|
clr al ; for scasb to find end
|
|
|
|
@@: cmp ah,[edi]
|
|
jz @F ; Found char
|
|
scasb
|
|
jnz @B ; Not end
|
|
dec edi ; Not found, point at end of string
|
|
@@: mov eax,edi
|
|
mov edi,edx ; Restore
|
|
pop ebp
|
|
ret
|
|
_strcend ENDP
|
|
endcode strcend
|
|
|
|
;
|
|
; Test if string has a given suffix
|
|
;
|
|
|
|
begcode is_prefix
|
|
public _is_prefix
|
|
_is_prefix proc near
|
|
fix_es 1
|
|
mov edx,edi ; Save edi
|
|
mov eax,esi ; Save esi
|
|
mov esi,P[esp] ; get suffix
|
|
mov edi,P-SIZEPTR[esp] ; s1
|
|
push eax ; push esi
|
|
mov eax,1 ; Ok and zero-test
|
|
@@: cmp ah,[esi]
|
|
jz suf_ok ; End of string; found suffix
|
|
cmpsb ; Compare strings
|
|
jz @B ; Same, possible prefix
|
|
xor eax,eax ; Not suffix
|
|
suf_ok: pop esi
|
|
mov edi,edx
|
|
ret
|
|
_is_prefix endp
|
|
endcode _is_prefix
|
|
|
|
;
|
|
; Find a substring in string
|
|
; Arg: str,search
|
|
;
|
|
|
|
begcode strstr
|
|
public _strstr
|
|
_strstr proc near
|
|
push ebp
|
|
mov ebp,esp
|
|
fix_es 1
|
|
push EDI
|
|
push ESI
|
|
mov esi,P[ebp] ; str
|
|
mov edi,P+SIZEPTR[ebp] ; search
|
|
mov ecx,edi
|
|
inc ecx ; ECX = search+1
|
|
mov ah,[edi] ; AH = First char in search
|
|
jmps sf_10
|
|
|
|
sf_00: mov esi,edx ; si = Current str-pos
|
|
sf_10: mov al,[esi] ; Test if this char exist
|
|
and al,al
|
|
jz sf_90 ; End of string, didn't find search
|
|
inc esi
|
|
cmp al,ah
|
|
jnz sf_10 ; Didn't find first char, continue
|
|
mov edx,esi ; Save str-pos in EDX
|
|
mov edi,ecx
|
|
sf_20: cmp BYTE PTR [edi],0
|
|
jz sf_fo ; Found substring
|
|
cmpsb
|
|
jz sf_20 ; Char ok
|
|
jmps sf_00 ; Next str-pos
|
|
|
|
sf_90: mov edx,1 ; Return Null
|
|
sf_fo: mov eax,edx ; Char found here
|
|
dec eax ; Pointed one after
|
|
pop ESI
|
|
pop EDI
|
|
pop ebp
|
|
ret
|
|
_strstr endp
|
|
endcode strstr
|
|
|
|
;
|
|
; Find a substring in string, return index
|
|
; Arg: str,search
|
|
;
|
|
|
|
begcode strinstr
|
|
public _strinstr
|
|
_strinstr proc near
|
|
push ebp
|
|
mov ebp,esp
|
|
push P+SIZEPTR[ebp] ; search
|
|
push P[ebp] ; str
|
|
call _strstr
|
|
add esp,SIZEPTR*2
|
|
or eax,eax
|
|
jz si_99 ; Not found, return NULL
|
|
sub eax,P[ebp] ; Pos from start
|
|
inc eax ; And first pos = 1
|
|
si_99: pop ebp
|
|
ret
|
|
_strinstr endp
|
|
endcode strinstr
|
|
|
|
;
|
|
; Make a string of len length from another string
|
|
; Arg: dst,src,length
|
|
; ret: end of dst
|
|
;
|
|
|
|
begcode strmake
|
|
public _strmake
|
|
_strmake proc near
|
|
push ebp
|
|
mov ebp,esp
|
|
fix_es 1
|
|
push EDI
|
|
push ESI
|
|
mov edi,P[ebp] ; dst
|
|
mov esi,P+SIZEPTR[ebp] ; src
|
|
mov ecx,P+SIZEPTR*2[ebp] ; Length of memory-area
|
|
clr al ; For test of end-null
|
|
jcxz sm_90 ; Nothing to move, put zero at end.
|
|
|
|
@@: cmp al,[esi] ; Next char to move
|
|
movsb ; move arg
|
|
jz sm_99 ; last char, we are ready
|
|
loop @B ; Continue moving
|
|
sm_90: mov BYTE PTR [edi],al ; Set end pos
|
|
inc edi ; Fix that di points at end null
|
|
sm_99: dec edi ; di points now at end null
|
|
mov eax,edi ; Ret value in DX:AX
|
|
pop ESI
|
|
pop EDI
|
|
pop ebp
|
|
ret
|
|
_strmake ENDP
|
|
endcode strmake
|
|
|
|
;
|
|
; Find length of string with maxlength
|
|
; arg: str,maxlength
|
|
; ret: length
|
|
;
|
|
|
|
begcode strnlen
|
|
public _strnlen
|
|
_strnlen proc near
|
|
push ebp
|
|
mov ebp,esp
|
|
fix_es 1
|
|
push edi
|
|
mov edi,P[ebp] ; Str
|
|
mov ecx,P+SIZEPTR[ebp] ; length
|
|
mov edx,edi ; Save str to calc length
|
|
jcxz sn_10 ; Length = 0
|
|
clr al ; Find end of string
|
|
repne scasb ; Find strend or length
|
|
jnz sn_10
|
|
dec edi ; DI points at last null
|
|
sn_10: mov eax,edi
|
|
sub eax,edx ; Ax = length
|
|
pop edi
|
|
pop ebp
|
|
ret
|
|
_strnlen ENDP
|
|
endcode strnlen
|
|
|
|
;
|
|
; Move a string with max len chars
|
|
; arg: dst,src,len
|
|
; ret: pos to first null or dst+len
|
|
|
|
begcode strnmov
|
|
public _strnmov
|
|
_strnmov PROC near
|
|
push ebp
|
|
mov ebp,esp
|
|
fix_es 1
|
|
push EDI
|
|
push ESI
|
|
mov edi,P[ebp] ; dst
|
|
mov esi,P+SIZEPTR[ebp] ; src
|
|
mov ecx,P+(SIZEPTR*2)[ebp] ; length
|
|
jcxz snm_99 ; Nothing to do
|
|
clr al ; For test of end-null
|
|
|
|
@@: cmp al,[esi] ; Next char to move
|
|
movsb ; move arg
|
|
jz snm_20 ; last char, fill with null
|
|
loop @B ; Continue moving
|
|
inc edi ; Point two after last
|
|
snm_20: dec edi ; Point at first null (or last+1)
|
|
snm_99: mov eax,edi ; Pointer at last char
|
|
pop ESI
|
|
pop EDI
|
|
pop ebp
|
|
ret
|
|
_strnmov ENDP
|
|
endcode strnmov
|
|
|
|
;
|
|
; Zortech has this one in standard library
|
|
;
|
|
|
|
begcode strmov
|
|
public _strmov
|
|
_strmov proc near
|
|
mov ecx,esi ; Save old esi and edi
|
|
mov edx,edi
|
|
mov esi,P[esp] ; get source pointer (s2)
|
|
mov edi,P-SIZEPTR[esp] ; EDI -> s1
|
|
fix_es 1
|
|
@@: mov al,[esi]
|
|
movsb ; move arg
|
|
and al,al
|
|
jnz @B ; Not last
|
|
mov eax,edi
|
|
dec eax
|
|
mov esi,ecx ; Restore args
|
|
mov edi,edx
|
|
ret
|
|
_strmov endp
|
|
endcode strmov
|
|
|
|
endif ; M_I386
|
|
|
|
END
|