1 /* strtok (str, delim) -- Return next DELIM separated token from STR.
3 Copyright (C) 1996 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with the GNU C Library; see the file COPYING.LIB. If
19 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
24 /* This file can be used for three variants of the strtok function:
37 We do a common implementation here. */
39 #ifndef USE_AS_STRTOK_R
42 ASM_TYPE_DIRECTIVE (save_ptr, @object)
47 #define FUNCTION strtok
54 movl 4(%esp), %edx /* Get start of string. */
55 movl 8(%esp), %eax /* Get start of delimiter set. */
57 #if !defined (USE_AS_STRTOK_R) && defined (PIC)
58 pushl %ebx /* Save PIC register. */
61 addl $_GLOBAL_OFFSET_TABLE_+[.-Lhere], %ebx
64 /* If the pointer is NULL we have to use the stored value of
69 #ifdef USE_AS_STRTOK_R
70 /* The value is stored in the third argument. */
74 /* The value is in the local variable defined above. But
75 we have to take care for PIC code. */
79 movl save_ptr@GOTOFF(%ebx), %edx
84 /* First we create a table with flags for all possible characters.
85 For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
86 supported by the C string functions we have 256 characters.
87 Before inserting marks for the stop characters we clear the whole
88 table. The unrolled form is much faster than a loop. */
89 xorl %ecx, %ecx /* %ecx = 0 !!! */
91 pushl %ecx /* make a 256 bytes long block filled with 0 */
149 pushl $0 /* These immediate values make the label 2 */
150 pushl $0 /* to be aligned on a 16 byte boundary to */
151 pushl $0 /* get a better performance of the loop. */
156 /* For understanding the following code remember that %ecx == 0 now.
157 Although all the following instruction only modify %cl we always
158 have a correct zero-extended 32-bit value in %ecx. */
160 L2: movb (%eax), %cl /* get byte from stopset */
161 testb %cl, %cl /* is NUL char? */
162 jz L1 /* yes => start compare loop */
163 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
165 movb 1(%eax), %cl /* get byte from stopset */
166 testb $0xff, %cl /* is NUL char? */
167 jz L1 /* yes => start compare loop */
168 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
170 movb 2(%eax), %cl /* get byte from stopset */
171 testb $0xff, %cl /* is NUL char? */
172 jz L1 /* yes => start compare loop */
173 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
175 movb 3(%eax), %cl /* get byte from stopset */
176 addl $4, %eax /* increment stopset pointer */
177 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
178 testb $0xff, %cl /* is NUL char? */
179 jnz L2 /* no => process next dword from stopset */
181 L1: leal -4(%edx), %eax /* prepare loop */
183 /* We use a neat trick for the following loop. Normally we would
184 have to test for two termination conditions
185 1. a character in the stopset was found
187 2. the end of the string was found
188 As a sign that the character is in the stopset we store its
189 value in the table. The value of NUL is NUL so the loop
190 terminates for NUL in every case. */
192 L3: addl $4, %eax /* adjust pointer for full loop round */
194 movb (%eax), %cl /* get byte from string */
195 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
196 jz L4 /* no => start of token */
198 movb 1(%eax), %cl /* get byte from string */
199 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
200 jz L5 /* no => start of token */
202 movb 2(%eax), %cl /* get byte from string */
203 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
204 jz L6 /* no => start of token */
206 movb 3(%eax), %cl /* get byte from string */
207 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
208 jnz L3 /* yes => start of loop */
210 incl %eax /* adjust pointer */
214 /* Now we have to terminate the string. */
216 L4: leal -4(%eax), %edx /* We use %EDX for the next run. */
218 L7: addl $4, %edx /* adjust pointer for full loop round */
220 movb (%edx), %cl /* get byte from string */
221 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
222 je L8 /* yes => return */
224 movb 1(%edx), %cl /* get byte from string */
225 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
226 je L9 /* yes => return */
228 movb 2(%edx), %cl /* get byte from string */
229 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
230 je L10 /* yes => return */
232 movb 3(%edx), %cl /* get byte from string */
233 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
234 jne L7 /* no => start loop again */
236 incl %edx /* adjust pointer */
240 L8: /* Remove the stopset table. */
244 je LreturnNULL /* There was no token anymore. */
246 movb $0, (%edx) /* Terminate string. */
248 /* Are we at end of string? */
255 /* Store the pointer to the next character. */
256 #ifdef USE_AS_STRTOK_R
263 movl %edx, save_ptr@GOTOFF(%ebx)
272 /* Store current pointer for next round. */
273 #ifdef USE_AS_STRTOK_R
280 movl %edx, save_ptr@GOTOFF(%ebx)