Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
31 halyavin 1
; some strtok-like function
2
;
3
; Copyright (c) 2003 Thomas Mathys
4
; killer@vantage.ch
5
;
6
; This program is free software; you can redistribute it and/or modify
7
; it under the terms of the GNU General Public License as published by
8
; the Free Software Foundation; either version 2 of the License, or
9
; (at your option) any later version.
10
;
11
; This program is distributed in the hope that it will be useful,
12
; but WITHOUT ANY WARRANTY; without even the implied warranty of
13
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
; GNU General Public License for more details.
15
;
16
; You should have received a copy of the GNU General Public License
17
; along with this program; if not, write to the Free Software
18
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
;
20
%ifndef _STRTOK_INC
21
%define _STRTOK_INC
22
 
23
 
24
;********************************************************************
25
;	strtok
26
;	this function works like strtok from a c runtime library.
27
;	note that it is not threadsafe. it would be an easy task
28
;	to make it threadsafe, though:
29
;	.adx must be removed, instead the last search address is
30
;	stored at some location provided by the user (passed as
31
;	a third parameter in ecx or so)
32
;
33
;	input:
34
;
35
;	eax	:	address of string to be searched (asciiz), or
36
;			0 to get the next token of the current string
37
;	ebx	:	address of delimiter list (asciiz)
38
;
39
;	output:
40
;
41
;	eax	:	pointer to the next token, or 0 if there
42
;			aren't any tokens anymore.
43
;
44
;	destroys:	nothing
45
;
46
;********************************************************************
47
strtok:
48
	pushad
49
	pushfd
50
 
51
	; get start address
52
	; if the new start address is 0, and the old address (.adx)
53
	; is also 0, then there's nothing to do and we return 0.
54
	or	eax,eax			; new address =  0 ?
55
	jz	.nonewstring		; nope -> use old string
56
	mov	[.adx],eax		; yeah -> store new string adx
57
.nonewstring:
58
	mov	esi,[.adx]		; load string address
59
	or	esi,esi			; 0 ?
60
	jnz	.startadxok		; nope -> ok
61
	xor	eax,eax			; yeah -> return 0
62
	je	.bye
63
.startadxok:
64
 
65
	; skip leading delimiters
66
.skipdelimiters:
67
	lodsb				; read character
68
	mov	edi,ebx			; edi -> delimiter list
69
.foo:
70
	mov	cl,[edi]		; get delimiter
71
	inc	edi
72
	or	cl,cl			; end of delimiter list
73
	jz	.endofdelimiterlist
74
	cmp	al,cl			; if AL is a delimiter, then
75
	je	.skipdelimiters		; we need to skip it too...
76
	jmp	.foo			; otherwise try next delimiter
77
.endofdelimiterlist:
78
 
79
	; end of string reached without finding any non-delimiters ?
80
	or	al,al			; character = 0 ?
81
	jnz	.bar			; nope -> continue
82
	mov	dword [.adx],0		; yeah -> remember this
83
	xor	eax,eax			; and return 0
84
	jmp	.bye
85
.bar:
86
 
87
	; found the start of a token, let's store its address
88
	mov	edx,esi
89
	dec	edx			; edx = start address of token
90
 
91
	; find the end of the token
92
.abraham:
93
	lodsb				; get character
94
	mov	edi,ebx			; edi -> delimiter list
95
.bebraham:
96
	mov	cl,[edi]		; get delimiter
97
	inc	edi
98
	cmp	al,cl			; is AL a delimiter ?
99
	jne	.cebraham		; nope -> continue
100
	or	al,al			; terminating zero found ?
101
	jnz	.argle
102
	xor	esi,esi			; yeah -> remember this
103
	jmp	.bargle
104
.argle:
105
	mov	byte [esi-1],0		; nope -> mark end of token
106
.bargle:
107
	mov	[.adx],esi		; remember search address
108
	mov	eax,edx			; return token address
109
	jmp	.bye
110
.cebraham:
111
	or	cl,cl			; end of delimiter list ?
112
	jnz	.bebraham		; nope -> try next delimiter
113
	jmp	.abraham
114
 
115
	; write return value into stack, so that when popad
116
	; gets executed, eax will receive the return value.
117
.bye:
118
	mov	[esp+4*8],eax
119
	popfd
120
	popad
121
	ret
122
.adx	dd	0
123
 
124
%endif
125