| 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 */ |