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