1 /* strtok (str, delim) -- Return next DELIM separated token from STR.
3 Copyright (C) 1998-2013 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"
26 /* This file can be used for three variants of the strtok function:
39 We do a common implementation here. */
41 #ifdef USE_AS_STRTOK_R
42 # define SAVE_PTR 0(%ecx)
46 .type save_ptr, @object
52 # define SAVE_PTR save_ptr@GOTOFF(%ebx)
54 # define SAVE_PTR save_ptr
57 # define FUNCTION strtok
60 #if !defined USE_AS_STRTOK_R && defined PIC
61 # define PARMS LINKAGE+256+4 /* space for table and saved PIC register */
63 # define PARMS LINKAGE+256 /* space for table */
66 #define STR RTN+RTN_SIZE
67 #define DELIM STR+PTR_SIZE
68 #ifdef USE_AS_STRTOK_R
69 # define SAVE DELIM+PTR_SIZE
74 #if !defined USE_AS_STRTOK_R && defined PIC
79 ENTRY (BP_SYM (FUNCTION))
81 #if !defined USE_AS_STRTOK_R && defined PIC
82 pushl %ebx /* Save PIC register. */
83 cfi_adjust_cfa_offset (4)
84 cfi_rel_offset (ebx, 0)
86 addl $_GLOBAL_OFFSET_TABLE_, %ebx
89 /* First we create a table with flags for all possible characters.
90 For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
91 supported by the C string functions we have 256 characters.
92 Before inserting marks for the stop characters we clear the whole
96 cfi_adjust_cfa_offset (256)
104 /* Note: %ecx = 0 !!! */
107 movl STR(%esp), %edx /* Get start of string. */
109 #ifdef USE_AS_STRTOK_R
110 /* The value is stored in the third argument. */
111 movl SAVE(%esp), %eax
114 /* The value is in the local variable defined above. But
115 we have to take care for PIC code. */
119 /* If the pointer is NULL we have to use the stored value of
125 movl DELIM(%esp), %eax /* Get start of delimiter set. */
127 /* For understanding the following code remember that %ecx == 0 now.
128 Although all the following instruction only modify %cl we always
129 have a correct zero-extended 32-bit value in %ecx. */
131 L(2): movb (%eax), %cl /* get byte from stopset */
132 testb %cl, %cl /* is NUL char? */
133 jz L(1) /* yes => start compare loop */
134 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
136 movb 1(%eax), %cl /* get byte from stopset */
137 testb $0xff, %cl /* is NUL char? */
138 jz L(1) /* yes => start compare loop */
139 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
141 movb 2(%eax), %cl /* get byte from stopset */
142 testb $0xff, %cl /* is NUL char? */
143 jz L(1) /* yes => start compare loop */
144 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
146 movb 3(%eax), %cl /* get byte from stopset */
147 addl $4, %eax /* increment stopset pointer */
148 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
149 testb $0xff, %cl /* is NUL char? */
150 jnz L(2) /* no => process next dword from stopset */
152 L(1): leal -4(%edx), %eax /* prepare loop */
154 /* We use a neat trick for the following loop. Normally we would
155 have to test for two termination conditions
156 1. a character in the stopset was found
158 2. the end of the string was found
159 As a sign that the character is in the stopset we store its
160 value in the table. The value of NUL is NUL so the loop
161 terminates for NUL in every case. */
163 L(3): addl $4, %eax /* adjust pointer for full loop round */
165 movb (%eax), %cl /* get byte from string */
166 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
167 jz L(4) /* no => start of token */
169 movb 1(%eax), %cl /* get byte from string */
170 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
171 jz L(5) /* no => start of token */
173 movb 2(%eax), %cl /* get byte from string */
174 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
175 jz L(6) /* no => start of token */
177 movb 3(%eax), %cl /* get byte from string */
178 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
179 jnz L(3) /* yes => start of loop */
181 incl %eax /* adjust pointer */
185 /* Now we have to terminate the string. */
187 L(4): leal -4(%eax), %edx /* We use %EDX for the next run. */
189 L(7): addl $4, %edx /* adjust pointer for full loop round */
191 movb (%edx), %cl /* get byte from string */
192 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
193 je L(8) /* yes => return */
195 movb 1(%edx), %cl /* get byte from string */
196 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
197 je L(9) /* yes => return */
199 movb 2(%edx), %cl /* get byte from string */
200 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
201 je L(10) /* yes => return */
203 movb 3(%edx), %cl /* get byte from string */
204 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
205 jne L(7) /* no => start loop again */
207 incl %edx /* adjust pointer */
211 L(8): cmpl %eax, %edx
212 je L(returnNULL) /* There was no token anymore. */
214 movb $0, (%edx) /* Terminate string. */
216 /* Are we at end of string? */
221 /* Store the pointer to the next character. */
222 #ifdef USE_AS_STRTOK_R
223 movl SAVE(%esp), %ecx
228 /* Remove the stopset table. */
230 cfi_adjust_cfa_offset (-256)
231 #if !defined USE_AS_STRTOK_R && defined PIC
233 cfi_adjust_cfa_offset (-4)
240 #ifdef USE_AS_STRTOK_R
241 movl SAVE(%esp), %ecx
246 END (BP_SYM (FUNCTION))