27 |
POSSIBILITY OF SUCH DAMAGE. |
POSSIBILITY OF SUCH DAMAGE. |
28 |
|
|
29 |
*/ |
*/ |
30 |
|
|
31 |
|
/* $Id$ */ |
32 |
|
|
33 |
/** \ingroup avr_string |
/** \ingroup avr_string |
34 |
\fn char *strsep(char **string, const char *delim) |
\fn char *strsep(char **string, const char *delim) |
35 |
\brief Parse a string into tokens. |
\brief Parse a string into tokens. |
49 |
|
|
50 |
#if !defined(DOXYGEN) |
#if !defined(DOXYGEN) |
51 |
|
|
|
#include "gasava.inc" |
|
52 |
#include "macros.inc" |
#include "macros.inc" |
53 |
#define X_hi r27 |
|
|
#define X_lo r26 |
|
54 |
#define p_str_hi r25 |
#define p_str_hi r25 |
55 |
#define p_str_lo r24 |
#define p_str_lo r24 |
56 |
#define del_hi r23 |
#define del_hi r23 |
62 |
|
|
63 |
.text |
.text |
64 |
.global _U(strsep) |
.global _U(strsep) |
65 |
.type _U(strsep),@function |
.type _U(strsep),@function |
66 |
|
|
67 |
_U(strsep): ; Check on NULL pointers |
_U(strsep): ; Check on NULL pointers |
68 |
LOAD_X (p_str_lo, p_str_hi) |
X_movw XL, p_str_lo |
69 |
LD str_lo, X+ |
LD str_lo, X+ |
70 |
LD str_hi, X ; str = *p_str |
LD str_hi, X ; str = *p_str |
71 |
CP str_lo, __zero_reg__ |
CP str_lo, __zero_reg__ |
72 |
CPC str_hi, __zero_reg__ ; str == NULL ? |
CPC str_hi, __zero_reg__ ; str == NULL ? |
73 |
BRNE .str_scan_init |
BRNE .L_str_scan_init |
74 |
CLR p_str_lo |
CLR p_str_lo |
75 |
CLR p_str_hi |
CLR p_str_hi |
76 |
RET ; return(NULL) |
RET ; return(NULL) |
77 |
|
|
78 |
.str_scan_init: ; scan string |
.L_str_scan_init: ; scan string |
79 |
LOAD_X (str_lo, str_hi) ; X = str |
X_movw XL, str_lo ; X = str |
|
PUSH X_lo |
|
|
PUSH X_hi ; save pointer to token |
|
80 |
|
|
81 |
.scan_str_loop: ; next str char, 1st del char |
.L_scan_str_loop: ; next str char, 1st del char |
82 |
LD str_c, X+ ; str_c = *str++ |
LD str_c, X+ ; str_c = *str++ |
83 |
LOAD_Z (del_lo, del_hi) ; Z = del |
X_movw ZL, del_lo ; Z = del |
84 |
|
|
85 |
.scan_del_loop: |
.L_scan_del_loop: |
86 |
LD del_c, Z+ ; del_c = *Z |
LD del_c, Z+ ; del_c = *Z |
87 |
CP del_c, str_c ; if (del_c == str_c) |
CP del_c, str_c ; if (del_c == str_c) |
88 |
BRNE 3f |
BRNE 3f |
89 |
TST str_c ; end of str ? |
TST str_c ; end of str ? |
90 |
BRNE 1f |
BRNE 1f |
91 |
CLR X_lo |
CLR XL |
92 |
CLR X_hi ; str = NULL |
CLR XH ; str = NULL |
93 |
RJMP 2f |
RJMP 2f |
94 |
1: ST -X, __zero_reg__ ; str[-1] = \0 |
1: ST -X, __zero_reg__ ; str[-1] = \0 |
95 |
ADIW X_lo, 1 ; undo auto decrement |
ADIW XL, 1 ; undo auto decrement |
96 |
2: LOAD_Z (p_str_lo, p_str_hi) |
2: X_movw ZL, p_str_lo |
97 |
ST Z+, X_lo |
ST Z+, XL |
98 |
ST Z, X_hi ; *string = str |
ST Z, XH ; *string = str |
99 |
POP p_str_hi |
X_movw p_str_lo, str_lo |
|
POP p_str_lo |
|
100 |
RET ; return(token) |
RET ; return(token) |
101 |
3: TST del_c ; end of del string ? |
3: TST del_c ; end of del string ? |
102 |
BRNE .scan_del_loop ; next del char, same str_char |
BRNE .L_scan_del_loop ; next del char, same str_char |
103 |
RJMP .scan_str_loop ; next str char, 1st del char |
RJMP .L_scan_str_loop ; next str char, 1st del char |
104 |
|
|
105 |
.strsep_end: |
.L_strsep_end: |
106 |
.size _U(strsep), .strsep_end - _U(strsep) |
.size _U(strsep), .L_strsep_end - _U(strsep) |
107 |
|
|
108 |
#endif /* not DOXYGEN */ |
#endif /* not DOXYGEN */ |