1/* Copyright (c) 2003, 2007 Reiner Patommel
2   Copyright (c) 2007  Dmitry Xmelkov
3   All rights reserved.
4
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions are met:
7
8   * Redistributions of source code must retain the above copyright
9     notice, this list of conditions and the following disclaimer.
10   * Redistributions in binary form must reproduce the above copyright
11     notice, this list of conditions and the following disclaimer in
12     the documentation and/or other materials provided with the
13     distribution.
14   * Neither the name of the copyright holders nor the names of
15     contributors may be used to endorse or promote products derived
16     from this software without specific prior written permission.
17
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  POSSIBILITY OF SUCH DAMAGE. */
29
30/* $Id: strsep.S 2191 2010-11-05 13:45:57Z arcanum $ */
31
32/** \file */
33
34/** \ingroup avr_string
35    \fn char *strsep(char **sp, const char *delim)
36    \brief Parse a string into tokens.
37
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'.
46
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
49    \c NULL.	*/
50
51#if !defined(__AVR_TINY__)
52
53#if !defined(__DOXYGEN__)
54
55#include "macros.inc"
56
57#define strp_lo	r24
58#define dlm_lo	r22
59#define str_lo	r20
60#define chr	r19
61
62#define ret_lo	r24
63
64	ASSEMBLY_CLIB_SECTION
65	.global _U(strsep)
66	.type	_U(strsep),@function
67_U(strsep):
68  ; check a NULL pointer
69	X_movw	ZL, strp_lo
70	ld	XL, Z			; str address
71	ldd	XH, Z+1
72	X_movw	str_lo, XL		; save for return
73	adiw	XL, 0
74	breq	5f			; return NULL
75  ; get a symbol from str
761:	ld	chr, X+
77  ; scan delim[]
78	X_movw	ZL, dlm_lo
792:	ld	r0, Z+
80	cp	r0, chr
81	cpse	r0, __zero_reg__
82	brne	2b	; if symbol is't match && no delim end
83	brne	1b	; if symbol is absent in delim[] && not a zero
84  ; chr is founded in delim[] (possible, it is a terminating zero of str)
85	tst	r0			; the same, as chr
86	brne	3f
87	X_movw	XL, r0			; __zero_reg__ is r1
88	rjmp	4f
89  ; OK, delimeter symbol is founded
903:	st	-X, __zero_reg__	; replace by '\0'
91	adiw	XL, 1			; address of next token
92  ; save result to *sp and return
934:	X_movw	ZL, strp_lo
94	st	Z, XL
95	std	Z+1, XH
965:	X_movw	ret_lo, str_lo		; return original address
97	ret
98
99	.size	_U(strsep), . - _U(strsep)
100
101#endif /* not __DOXYGEN__ */
102
103#endif /* !defined(__AVR_TINY__) */
104