| 28 |
|
|
| 29 |
*/ |
*/ |
| 30 |
|
|
| 31 |
|
/* $Id$ */ |
| 32 |
|
|
| 33 |
/** \ingroup avr_string |
/** \ingroup avr_string |
| 34 |
\fn char *strtok_r(char *string, const char *delim, char **last) |
\fn char *strtok_r(char *string, const char *delim, char **last) |
| 35 |
\brief Parses the string s into tokens. |
\brief Parses the string s into tokens. |
| 48 |
|
|
| 49 |
#if !defined(DOXYGEN) |
#if !defined(DOXYGEN) |
| 50 |
|
|
|
#include "gasava.inc" |
|
| 51 |
#include "macros.inc" |
#include "macros.inc" |
| 52 |
|
|
|
#define X_hi r27 |
|
|
#define X_lo r26 |
|
| 53 |
#define str_hi r25 |
#define str_hi r25 |
| 54 |
#define str_lo r24 |
#define str_lo r24 |
| 55 |
#define del_hi r23 |
#define del_hi r23 |
| 61 |
|
|
| 62 |
.text |
.text |
| 63 |
.global _U(strtok_r) |
.global _U(strtok_r) |
| 64 |
.type _U(strtok_r), @function |
.type _U(strtok_r), @function |
| 65 |
|
|
| 66 |
_U(strtok_r): ; Check on NULL pointers |
_U(strtok_r): ; Check on NULL pointers |
| 67 |
SBIW str_lo, 0 ; str == NULL ? |
SBIW str_lo, 0 ; str == NULL ? |
| 68 |
BRNE .del_lead_init ; here 1st call to strtok_r |
BRNE .L_del_lead_init ; here 1st call to strtok_r |
| 69 |
LOAD_X (last_lo, last_hi) |
X_movw XL, last_lo |
| 70 |
LD str_lo, X+ |
LD str_lo, X+ |
| 71 |
LD str_hi, X ; |
LD str_hi, X ; |
| 72 |
SBIW str_lo, 0 ; last == NULL ? |
SBIW str_lo, 0 ; last == NULL ? |
| 73 |
BRNE .del_lead_init ; here nth call to strtok_r |
BRNE .L_del_lead_init ; here nth call to strtok_r |
| 74 |
RJMP 2f ; no more to do |
RJMP 2f ; no more to do |
| 75 |
|
|
| 76 |
.del_lead_init: ; Remove leading delimiters |
.L_del_lead_init: ; Remove leading delimiters |
| 77 |
LOAD_X (str_lo, str_hi) |
X_movw XL, str_lo |
| 78 |
|
|
| 79 |
.del_str_loop: |
.L_del_str_loop: |
| 80 |
LOAD_Z (del_lo, del_hi) ; Z = *delim |
X_movw ZL, del_lo ; Z = *delim |
| 81 |
LD str_c, X+ ; str_c = *string++ |
LD str_c, X+ ; str_c = *string++ |
| 82 |
|
|
| 83 |
.del_loop: |
.L_del_loop: |
| 84 |
LD del_c, Z+ ; del_c = *Z |
LD del_c, Z+ ; del_c = *Z |
| 85 |
TST del_c ; end of del string ? |
TST del_c ; end of del string ? |
| 86 |
BREQ 1f ; yes: -> done with leading delimiters |
BREQ 1f ; yes: -> done with leading delimiters |
| 87 |
CP str_c, del_c |
CP str_c, del_c |
| 88 |
BREQ .del_str_loop ; match: -> next str_char, 1st del_char |
BREQ .L_del_str_loop ; match: -> next str_char, 1st del_char |
| 89 |
RJMP .del_loop ; next del_char, same str_char |
RJMP .L_del_loop ; next del_char, same str_char |
| 90 |
1: TST str_c ; end of str ? |
1: TST str_c ; end of str ? |
| 91 |
BRNE .str_scan_init ; no: -> scan |
BRNE .L_str_scan_init ; no: -> scan |
| 92 |
LOAD_X (last_lo, last_hi) |
X_movw XL, last_lo |
| 93 |
ST X+, __zero_reg__ |
ST X+, __zero_reg__ |
| 94 |
ST X, __zero_reg__ ; last = NULL |
ST X, __zero_reg__ ; last = NULL |
| 95 |
2: CLR str_lo |
2: CLR str_lo |
| 96 |
CLR str_hi |
CLR str_hi |
| 97 |
RET ; return(NULL) |
RET ; return(NULL) |
| 98 |
|
|
| 99 |
.str_scan_init: ; scan string |
.L_str_scan_init: ; scan string |
| 100 |
SBIW X_lo, 1 ; X points to token |
SBIW XL, 1 ; X points to token |
| 101 |
PUSH X_lo |
PUSH XL |
| 102 |
PUSH X_hi ; save pointer to token |
PUSH XH ; save pointer to token |
| 103 |
|
|
| 104 |
.scan_str_loop: ; next str char, 1st del char |
.L_scan_str_loop: ; next str char, 1st del char |
| 105 |
LOAD_Z (del_lo, del_hi) ; Z points to del str |
X_movw ZL, del_lo ; Z points to del str |
| 106 |
LD str_c, X+ ; str_c = *string++ |
LD str_c, X+ ; str_c = *string++ |
| 107 |
|
|
| 108 |
.scan_del_loop: |
.L_scan_del_loop: |
| 109 |
LD del_c, Z+ ; del_c = *Z |
LD del_c, Z+ ; del_c = *Z |
| 110 |
CP str_c, del_c |
CP str_c, del_c |
| 111 |
BRNE 3f |
BRNE 3f |
| 113 |
BRNE 1f |
BRNE 1f |
| 114 |
CLR str_lo |
CLR str_lo |
| 115 |
CLR str_hi ; str = NULL |
CLR str_hi ; str = NULL |
| 116 |
SBIW X_lo, 1 ; undo auto increment |
SBIW XL, 1 ; undo auto increment |
| 117 |
RJMP 2f |
RJMP 2f |
| 118 |
1: ST -X, __zero_reg__ ; str[-1] = \0 |
1: ST -X, __zero_reg__ ; str[-1] = \0 |
| 119 |
ADIW X_lo, 1 ; undo auto decrement |
ADIW XL, 1 ; undo auto decrement |
| 120 |
2: LOAD_Z (last_lo, last_hi) |
2: X_movw ZL, last_lo |
| 121 |
ST Z+, X_lo |
ST Z+, XL |
| 122 |
ST Z, X_hi ; *last = str |
ST Z, XH ; *last = str |
| 123 |
POP str_hi |
POP str_hi |
| 124 |
POP str_lo ; get pointer to token again |
POP str_lo ; get pointer to token again |
| 125 |
RET ; return(token) |
RET ; return(token) |
| 126 |
3: TST del_c ; end of del string ? |
3: TST del_c ; end of del string ? |
| 127 |
BRNE .scan_del_loop ; next del char, same str_char |
BRNE .L_scan_del_loop ; next del char, same str_char |
| 128 |
RJMP .scan_str_loop ; next str char, 1st del char |
RJMP .L_scan_str_loop ; next str char, 1st del char |
| 129 |
|
|
| 130 |
.strtok_r_end: |
.L_strtok_r_end: |
| 131 |
.size _U(strtok_r), .strtok_r_end - _U(strtok_r) |
.size _U(strtok_r), .L_strtok_r_end - _U(strtok_r) |
| 132 |
|
|
| 133 |
#endif /* not DOXYGEN */ |
#endif /* not DOXYGEN */ |