~ubuntu-branches/ubuntu/maverick/avr-libc/maverick

« back to all changes in this revision

Viewing changes to libc/string/strsep.S

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2007-08-09 11:28:01 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070809112801-ps7wognnynio9kz7
Tags: 1:1.4.6-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2003, Reiner Patommel
 
1
/* Copyright (c) 2003, 2007 Reiner Patommel
 
2
   Copyright (c) 2007  Dmitry Xmelkov
2
3
   All rights reserved.
3
4
 
4
5
   Redistribution and use in source and binary forms, with or without
24
25
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
26
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
27
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
 
  POSSIBILITY OF SUCH DAMAGE.
28
 
 
29
 
 */
30
 
 
31
 
/* $Id: strsep.S,v 1.5 2005/11/02 22:08:03 aesok Exp $ */
32
 
 
33
 
 /** \ingroup avr_string
34
 
     \fn char *strsep(char **string, const char *delim)
35
 
     \brief Parse a string into tokens.
36
 
 
37
 
     The strsep() function locates, in the string referenced by *string,
38
 
     the first occurrence of any character in the string delim (or the
39
 
     terminating '\\0' character) and replaces it with a '\\0'.  The location
40
 
     of the next character after the delimiter character (or NULL, if the
41
 
     end of the string was reached) is stored in *string. An ``empty''
42
 
     field, i.e. one caused by two adjacent delimiter characters, can be
43
 
     detected by comparing the location referenced by the pointer returned
44
 
     in *string to '\\0'.
45
 
   
46
 
     \returns The strtok_r() function returns a pointer to the original
47
 
     value of *string.  If *stringp is initially NULL, strsep() returns NULL.
48
 
 */
 
28
  POSSIBILITY OF SUCH DAMAGE. */
 
29
 
 
30
/* $Id: strsep.S,v 1.5.2.2 2007/03/31 13:28:29 dmix Exp $ */
 
31
 
 
32
/** \file */
 
33
 
 
34
/** \ingroup avr_string
 
35
    \fn char *strsep(char **sp, const char *delim)
 
36
    \brief Parse a string into tokens.
 
37
 
 
38
    The strsep() function locates, in the string referenced by \p *sp,
 
39
    the first occurrence of any character in the string \p delim (or the
 
40
    terminating '\\0' character) and replaces it with a '\\0'.  The
 
41
    location of the next character after the delimiter character (or \c
 
42
    NULL, if the end of the string was reached) is stored in \p *sp. An
 
43
    ``empty'' field, i.e. one caused by two adjacent delimiter
 
44
    characters, can be detected by comparing the location referenced by
 
45
    the pointer returned in \p *sp to '\\0'.
 
46
 
 
47
    \return The strsep() function returns a pointer to the original
 
48
    value of \p *sp. If \p *sp is initially \c NULL, strsep() returns
 
49
    \c NULL.    */
49
50
     
50
51
#if !defined(__DOXYGEN__)
51
52
 
52
53
#include "macros.inc"
53
54
 
54
 
#define p_str_hi        r25
55
 
#define p_str_lo        r24
56
 
#define del_hi          r23
57
 
#define del_lo          r22
58
 
#define str_hi          r21
59
 
#define str_lo          r20
60
 
#define str_c           r19
61
 
#define del_c           r18
 
55
#define strp_lo r24
 
56
#define dlm_lo  r22
 
57
#define str_lo  r20
 
58
#define chr     r19
 
59
 
 
60
#define ret_lo  r24
62
61
 
63
62
        .text
64
63
        .global _U(strsep)
65
64
        .type   _U(strsep),@function
66
 
 
67
 
_U(strsep):                             ; Check on NULL pointers
68
 
        X_movw  XL, p_str_lo
69
 
        LD      str_lo, X+
70
 
        LD      str_hi, X               ; str = *p_str
71
 
        CP      str_lo, __zero_reg__
72
 
        CPC     str_hi, __zero_reg__    ; str == NULL ?
73
 
        BRNE    .L_str_scan_init
74
 
        CLR     p_str_lo
75
 
        CLR     p_str_hi
76
 
        RET                             ; return(NULL)
77
 
 
78
 
.L_str_scan_init:                       ; scan string
79
 
        X_movw  XL, str_lo              ; X = str
80
 
 
81
 
.L_scan_str_loop:                       ; next str char, 1st del char
82
 
        LD      str_c, X+               ; str_c = *str++
83
 
        X_movw  ZL, del_lo              ; Z = del
84
 
 
85
 
.L_scan_del_loop:
86
 
        LD      del_c, Z+               ; del_c = *Z
87
 
        CP      del_c, str_c            ; if (del_c == str_c)
88
 
        BRNE    3f
89
 
        TST     str_c                   ; end of str ?
90
 
        BRNE    1f
91
 
        CLR     XL
92
 
        CLR     XH                      ; str = NULL
93
 
        RJMP    2f
94
 
1:      ST      -X, __zero_reg__        ; str[-1] = \0
95
 
        ADIW    XL, 1                   ; undo auto decrement
96
 
2:      X_movw  ZL, p_str_lo
97
 
        ST      Z+, XL
98
 
        ST      Z, XH                   ; *string = str
99
 
        X_movw  p_str_lo, str_lo 
100
 
        RET                             ; return(token)
101
 
3:      TST     del_c                   ; end of del string ?
102
 
        BRNE    .L_scan_del_loop        ; next del char, same str_char
103
 
        RJMP    .L_scan_str_loop        ; next str char, 1st del char
104
 
 
105
 
.L_strsep_end:
106
 
        .size   _U(strsep), .L_strsep_end - _U(strsep)
107
 
 
 
65
_U(strsep):
 
66
  ; check a NULL pointer
 
67
        X_movw  ZL, strp_lo
 
68
        ld      XL, Z                   ; str address
 
69
        ldd     XH, Z+1
 
70
        X_movw  str_lo, XL              ; save for return
 
71
        adiw    XL, 0
 
72
        breq    5f                      ; return NULL
 
73
  ; get a symbol from str
 
74
1:      ld      chr, X+
 
75
  ; scan delim[]
 
76
        X_movw  ZL, dlm_lo
 
77
2:      ld      r0, Z+
 
78
        cp      r0, chr
 
79
        cpse    r0, __zero_reg__
 
80
        brne    2b      ; if symbol is't match && no delim end
 
81
        brne    1b      ; if symbol is absent in delim[] && not a zero
 
82
  ; chr is founded in delim[] (possible, it is a terminating zero of str)
 
83
        tst     r0                      ; the same, as chr
 
84
        brne    3f
 
85
        X_movw  XL, r0                  ; __zero_reg__ is r1
 
86
        rjmp    4f
 
87
  ; OK, delimeter symbol is founded
 
88
3:      st      -X, __zero_reg__        ; replace by '\0'
 
89
        adiw    XL, 1                   ; address of next token
 
90
  ; save result to *sp and return
 
91
4:      X_movw  ZL, strp_lo
 
92
        st      Z, XL
 
93
        std     Z+1, XH
 
94
5:      X_movw  ret_lo, str_lo          ; return original address
 
95
        ret
 
96
 
 
97
        .size   _U(strsep), . - _U(strsep)
108
98
#endif /* not __DOXYGEN__ */