24
25
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
26
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
27
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
POSSIBILITY OF SUCH DAMAGE.
31
/* $Id: strsep.S,v 1.5 2005/11/02 22:08:03 aesok Exp $ */
33
/** \ingroup avr_string
34
\fn char *strsep(char **string, const char *delim)
35
\brief Parse a string into tokens.
37
The strsep() function locates, in the string referenced by *string,
38
the first occurrence of any character in the string delim (or the
39
terminating '\\0' character) and replaces it with a '\\0'. The location
40
of the next character after the delimiter character (or NULL, if the
41
end of the string was reached) is stored in *string. An ``empty''
42
field, i.e. one caused by two adjacent delimiter characters, can be
43
detected by comparing the location referenced by the pointer returned
46
\returns The strtok_r() function returns a pointer to the original
47
value of *string. If *stringp is initially NULL, strsep() returns NULL.
28
POSSIBILITY OF SUCH DAMAGE. */
30
/* $Id: strsep.S,v 1.5.2.2 2007/03/31 13:28:29 dmix Exp $ */
34
/** \ingroup avr_string
35
\fn char *strsep(char **sp, const char *delim)
36
\brief Parse a string into tokens.
38
The strsep() function locates, in the string referenced by \p *sp,
39
the first occurrence of any character in the string \p delim (or the
40
terminating '\\0' character) and replaces it with a '\\0'. The
41
location of the next character after the delimiter character (or \c
42
NULL, if the end of the string was reached) is stored in \p *sp. An
43
``empty'' field, i.e. one caused by two adjacent delimiter
44
characters, can be detected by comparing the location referenced by
45
the pointer returned in \p *sp to '\\0'.
47
\return The strsep() function returns a pointer to the original
48
value of \p *sp. If \p *sp is initially \c NULL, strsep() returns
50
51
#if !defined(__DOXYGEN__)
52
53
#include "macros.inc"
65
64
.type _U(strsep),@function
67
_U(strsep): ; Check on NULL pointers
70
LD str_hi, X ; str = *p_str
71
CP str_lo, __zero_reg__
72
CPC str_hi, __zero_reg__ ; str == NULL ?
78
.L_str_scan_init: ; scan string
79
X_movw XL, str_lo ; X = str
81
.L_scan_str_loop: ; next str char, 1st del char
82
LD str_c, X+ ; str_c = *str++
83
X_movw ZL, del_lo ; Z = del
86
LD del_c, Z+ ; del_c = *Z
87
CP del_c, str_c ; if (del_c == str_c)
89
TST str_c ; end of str ?
94
1: ST -X, __zero_reg__ ; str[-1] = \0
95
ADIW XL, 1 ; undo auto decrement
96
2: X_movw ZL, p_str_lo
98
ST Z, XH ; *string = str
99
X_movw p_str_lo, str_lo
101
3: TST del_c ; end of del string ?
102
BRNE .L_scan_del_loop ; next del char, same str_char
103
RJMP .L_scan_str_loop ; next str char, 1st del char
106
.size _U(strsep), .L_strsep_end - _U(strsep)
66
; check a NULL pointer
68
ld XL, Z ; str address
70
X_movw str_lo, XL ; save for return
73
; get a symbol from str
80
brne 2b ; if symbol is't match && no delim end
81
brne 1b ; if symbol is absent in delim[] && not a zero
82
; chr is founded in delim[] (possible, it is a terminating zero of str)
83
tst r0 ; the same, as chr
85
X_movw XL, r0 ; __zero_reg__ is r1
87
; OK, delimeter symbol is founded
88
3: st -X, __zero_reg__ ; replace by '\0'
89
adiw XL, 1 ; address of next token
90
; save result to *sp and return
94
5: X_movw ret_lo, str_lo ; return original address
97
.size _U(strsep), . - _U(strsep)
108
98
#endif /* not __DOXYGEN__ */