1 /* strtok (str, delim) -- Return next DELIM separated token from STR.
3 Copyright (C) 1998-2015 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the 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 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, see
19 <http://www.gnu.org/licenses/>. */
22 #include "asm-syntax.h"
24 /* This file can be used for three variants of the strtok function:
37 We do a common implementation here. */
39 #ifdef USE_AS_STRTOK_R
40 # define SAVE_PTR 0(%ecx)
44 .type save_ptr, @object
50 # define SAVE_PTR save_ptr@GOTOFF(%ebx)
52 # define SAVE_PTR save_ptr
55 # define FUNCTION strtok
58 #if !defined USE_AS_STRTOK_R && defined PIC
59 # define PARMS 4+256+4 /* space for table and saved PIC register */
61 # define PARMS 4+256 /* space for table */
66 #ifdef USE_AS_STRTOK_R
72 #if !defined USE_AS_STRTOK_R && defined PIC
79 #if !defined USE_AS_STRTOK_R && defined PIC
80 pushl %ebx /* Save PIC register. */
81 cfi_adjust_cfa_offset (4)
82 cfi_rel_offset (ebx, 0)
84 addl $_GLOBAL_OFFSET_TABLE_, %ebx
87 /* First we create a table with flags for all possible characters.
88 For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
89 supported by the C string functions we have 256 characters.
90 Before inserting marks for the stop characters we clear the whole
94 cfi_adjust_cfa_offset (256)
102 /* Note: %ecx = 0 !!! */
105 movl STR(%esp), %edx /* Get start of string. */
107 #ifdef USE_AS_STRTOK_R
108 /* The value is stored in the third argument. */
109 movl SAVE(%esp), %eax
112 /* The value is in the local variable defined above. But
113 we have to take care for PIC code. */
117 /* If the pointer is NULL we have to use the stored value of
123 movl DELIM(%esp), %eax /* Get start of delimiter set. */
125 /* For understanding the following code remember that %ecx == 0 now.
126 Although all the following instruction only modify %cl we always
127 have a correct zero-extended 32-bit value in %ecx. */
129 L(2): movb (%eax), %cl /* get byte from stopset */
130 testb %cl, %cl /* is NUL char? */
131 jz L(1) /* yes => start compare loop */
132 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
134 movb 1(%eax), %cl /* get byte from stopset */
135 testb $0xff, %cl /* is NUL char? */
136 jz L(1) /* yes => start compare loop */
137 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
139 movb 2(%eax), %cl /* get byte from stopset */
140 testb $0xff, %cl /* is NUL char? */
141 jz L(1) /* yes => start compare loop */
142 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
144 movb 3(%eax), %cl /* get byte from stopset */
145 addl $4, %eax /* increment stopset pointer */
146 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
147 testb $0xff, %cl /* is NUL char? */
148 jnz L(2) /* no => process next dword from stopset */
150 L(1): leal -4(%edx), %eax /* prepare loop */
152 /* We use a neat trick for the following loop. Normally we would
153 have to test for two termination conditions
154 1. a character in the stopset was found
156 2. the end of the string was found
157 As a sign that the character is in the stopset we store its
158 value in the table. The value of NUL is NUL so the loop
159 terminates for NUL in every case. */
161 L(3): addl $4, %eax /* adjust pointer for full loop round */
163 movb (%eax), %cl /* get byte from string */
164 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
165 jz L(4) /* no => start of token */
167 movb 1(%eax), %cl /* get byte from string */
168 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
169 jz L(5) /* no => start of token */
171 movb 2(%eax), %cl /* get byte from string */
172 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
173 jz L(6) /* no => start of token */
175 movb 3(%eax), %cl /* get byte from string */
176 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
177 jnz L(3) /* yes => start of loop */
179 incl %eax /* adjust pointer */
183 /* Now we have to terminate the string. */
185 L(4): leal -4(%eax), %edx /* We use %EDX for the next run. */
187 L(7): addl $4, %edx /* adjust pointer for full loop round */
189 movb (%edx), %cl /* get byte from string */
190 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
191 je L(8) /* yes => return */
193 movb 1(%edx), %cl /* get byte from string */
194 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
195 je L(9) /* yes => return */
197 movb 2(%edx), %cl /* get byte from string */
198 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
199 je L(10) /* yes => return */
201 movb 3(%edx), %cl /* get byte from string */
202 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
203 jne L(7) /* no => start loop again */
205 incl %edx /* adjust pointer */
209 L(8): cmpl %eax, %edx
210 je L(returnNULL) /* There was no token anymore. */
212 movb $0, (%edx) /* Terminate string. */
214 /* Are we at end of string? */
219 /* Store the pointer to the next character. */
220 #ifdef USE_AS_STRTOK_R
221 movl SAVE(%esp), %ecx
226 /* Remove the stopset table. */
228 cfi_adjust_cfa_offset (-256)
229 #if !defined USE_AS_STRTOK_R && defined PIC
231 cfi_adjust_cfa_offset (-4)
238 #ifdef USE_AS_STRTOK_R
239 movl SAVE(%esp), %ecx