1/* Copyright (c) 2003, 2007 Reiner Patommel 2 Copyright (c) 2009 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 31/* $Id: strtok_r.S 2191 2010-11-05 13:45:57Z arcanum $ */ 32 33/** \file */ 34 35/** \ingroup avr_string 36 \fn char *strtok_r(char *string, const char *delim, char **last) 37 \brief Parses string into tokens. 38 39 strtok_r parses string into tokens. The first call to strtok_r 40 should have string as its first argument. Subsequent calls should have 41 the first argument set to NULL. If a token ends with a delimiter, this 42 delimiting character is overwritten with a '\\0' and a pointer to the next 43 character is saved for the next call to strtok_r. The delimiter string 44 \p delim may be different for each call. \p last is a user allocated char* 45 pointer. It must be the same while parsing the same string. strtok_r is 46 a reentrant version of strtok(). 47 48 \returns The strtok_r() function returns a pointer to the next token or 49 NULL when no more tokens are found. */ 50 51#if !defined(__AVR_TINY__) 52 53#if !defined(__DOXYGEN__) 54 55#include "asmdef.h" 56 57/* char *strtok_r (char *s, const char *delim, char **last) 58 { 59 char *p = *last; 60 const char *q; 61 char c, d; 62 63 if (!s) { 64 if (!p) return s; // end of string 65 s = p; // continue parsing 66 } 67 68 p = s; 69 for (;;) { // skip delimeters 70 s = p; // space optimization (vs. s = p-1) 71 if (!(c = *p++)) { 72 s = 0; 73 p = 0; 74 goto ret; 75 } 76 q = delim; 77 do { 78 if (!(d = *q++)) 79 goto find_end; 80 } while (d != c); 81 } 82 83 find_end: 84 do { 85 q = delim; 86 do { 87 d = *q++; 88 if (c == d) { 89 *--p = 0; 90 p++; 91 goto ret; 92 } 93 } while (d); 94 } while ((c = *p++) != 0); 95 p = 0; // stop parsing 96 ret: 97 *last = p; 98 return s; 99 } 100 */ 101 102#define str_lo r24 103#define dlm_lo r22 104#define lst_lo r20 105#define dch r18 106 107ENTRY strtok_r 108 X_movw ZL, lst_lo 109 ld XL, Z+ ; X = *last 110 ld XH, Z 111 ; check str 112 sbiw str_lo, 0 113 brne 1f 114 sbiw XL, 0 115 breq .Lret ; end of string 116 X_movw str_lo, XL ; continue parsing 117 118 ; skip delimeters 1191: X_movw XL, str_lo ; p = str 1202: X_movw str_lo, XL 121 ld __tmp_reg__, X+ 122 tst __tmp_reg__ 123 brne 3f 124 X_movw str_lo, __tmp_reg__ ; <r0,r1> 125 rjmp .Lclr 1263: X_movw ZL, dlm_lo 1274: ld dch, Z+ 128 tst dch 129 breq 5f ; goto find 130 cp dch, __tmp_reg__ 131 brne 4b 132 rjmp 2b ; skip 1 byte 133 134 ; find new token end 1355: X_movw ZL, dlm_lo 1366: ld dch, Z+ 137 cp dch, __tmp_reg__ ; __tmp_reg__ != 0 138 brne 7f 139 st -X, __zero_reg__ 140 adiw XL, 1 141 rjmp .Lret 1427: tst dch 143 brne 6b 144 ; next str byte 145 ld __tmp_reg__, X+ 146 tst __tmp_reg__ 147 brne 5b 148 149 ; stop parsing 150.Lclr: X_movw XL, __tmp_reg__ ; <r0,r1> 151 ; save last pointer 152.Lret: X_movw ZL, lst_lo ; *last = X 153 st Z+, XL 154 st Z, XH 155 ret 156 157ENDFUNC 158 159#endif /* not __DOXYGEN__ */ 160 161#endif /* !defined(__AVR_TINY__) */ 162