~ubuntu-branches/ubuntu/hardy/avr-libc/hardy

« back to all changes in this revision

Viewing changes to libc/string/strcasestr.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) 2007  Dmitry Xmelkov
 
2
   All rights reserved.
 
3
 
 
4
   Redistribution and use in source and binary forms, with or without
 
5
   modification, are permitted provided that the following conditions are met:
 
6
 
 
7
   * Redistributions of source code must retain the above copyright
 
8
     notice, this list of conditions and the following disclaimer.
 
9
   * Redistributions in binary form must reproduce the above copyright
 
10
     notice, this list of conditions and the following disclaimer in
 
11
     the documentation and/or other materials provided with the
 
12
     distribution.
 
13
   * Neither the name of the copyright holders nor the names of
 
14
     contributors may be used to endorse or promote products derived
 
15
     from this software without specific prior written permission.
 
16
 
 
17
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
18
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
19
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
20
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
21
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
22
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
23
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
24
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
25
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
26
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
27
  POSSIBILITY OF SUCH DAMAGE. */
 
28
 
 
29
/* $Id: strcasestr.S,v 1.2.2.1 2007/03/31 13:23:16 dmix Exp $ */
 
30
 
 
31
/** \file */
 
32
 
 
33
/** \ingroup avr_string
 
34
    \fn char *strcasestr(const char *s1, const char *s2)
 
35
 
 
36
    The strcasestr() function finds the first occurrence of the
 
37
    substring \p s2 in the string \p s1. This is like strstr(), except
 
38
    that it ignores case of alphabetic symbols in searching for the
 
39
    substring. (Glibc, GNU extension.)
 
40
 
 
41
    \return The strcasestr() function returns a pointer to the beginning
 
42
    of the substring, or \c NULL if the substring is not found. If \p s2
 
43
    points to a string of zero length, the function returns \p s1. */
 
44
    
 
45
/** \ingroup avr_pgmspace
 
46
    \fn char *strcasestr_P(const char *s1, PGM_P s2)
 
47
    
 
48
    This funtion is similar to strcasestr() except that \p s2 is pointer
 
49
    to a string in program space.       */
 
50
 
 
51
#if !defined(__DOXYGEN__)
 
52
 
 
53
#include "asmdef.h"
 
54
 
 
55
#define s1_hi   r25
 
56
#define s1_lo   r24
 
57
#define s2_hi   r23
 
58
#define s2_lo   r22
 
59
 
 
60
#define beg2    r21     /* begin of s2 (cashed): s2[0]          */
 
61
#define ctmp    r20     /* scratch arg of .Lcmp()               */
 
62
#define csvd    r0      /* second arg of .Lcmp(), nochanged     */
 
63
 
 
64
#ifdef  Lprogmem
 
65
# define strcasestr     strcasestr_P
 
66
# define LOAD           X_lpm           /* may scratch r0       */
 
67
#else
 
68
# define LOAD           ld
 
69
#endif
 
70
 
 
71
ENTRY strcasestr
 
72
        X_movw  ZL, s2_lo
 
73
        LOAD    beg2, Z+
 
74
        tst     beg2            ; is str2 empty?
 
75
        breq    .L_ret          ; return original string (req'd by standard)
 
76
        X_movw  s2_lo, ZL       ; save: address of second s2 byte
 
77
 
 
78
1:      X_movw  XL, s1_lo
 
79
        mov     csvd, beg2      ; Find first char
 
80
 
 
81
2:      ld      ctmp, X+
 
82
        tst     ctmp
 
83
        breq    .L_nomatch      ; end of s1
 
84
        rcall   .Lcmp
 
85
        brne    2b
 
86
 
 
87
        X_movw  s1_lo, XL       ; store return value (decrement is needed)
 
88
 
 
89
3:      LOAD    csvd, Z+        ; compare strings (csvd is r0)
 
90
        tst     csvd
 
91
        breq    .L_match        ; end of s2
 
92
  ; Z==0
 
93
        ld      ctmp, X+
 
94
        cpse    ctmp, __zero_reg__      ; now Z==0
 
95
        rcall   .Lcmp
 
96
  ; (ctmp==0 && Z==0) ||        - end of s1
 
97
  ; (ctmp!=0 && Z==0) ||        - chars are not equal
 
98
  ; (Z==1)                      - chars are equal
 
99
        breq    3b
 
100
 
 
101
        X_movw  ZL, s2_lo               ; restore s2+1
 
102
  ; (ctmp==0 && Z==0) ||        - end of s2
 
103
  ; (ctmp!=0 && Z==0)           - chars are not equal
 
104
        cpse    ctmp, __zero_reg__      ; if equal, then tail(s1) is less
 
105
        rjmp    1b                      ;   then strlen(s2)
 
106
 
 
107
.L_nomatch:
 
108
        ldi     s1_lo, lo8(1)
 
109
        ldi     s1_hi, hi8(1)
 
110
.L_match:
 
111
        sbiw    s1_lo, 1        ; restore after post-increment
 
112
.L_ret:
 
113
        ret
 
114
 
 
115
/* Compare 2 bytes ignoring a case of symbols.
 
116
   Input:       ctmp, csvd.
 
117
   Return:      if (bytes are equal) Z==1, else (Z==0 && ctmp != 0)
 
118
   Scratch:     ctmp only.
 
119
 */
 
120
.if  ('a'-'A' - 0x20) | ('Z'-'A' - 25) | ('z'-'a' - 25)
 
121
    .err
 
122
.endif
 
123
.Lcmp:  eor     ctmp, csvd
 
124
        breq    1f              ; OK, bytes are equal
 
125
        cpi     ctmp, 0x20
 
126
        brne    1f              ; bytes are different more than alpha case
 
127
  ; now caseless comparison
 
128
        or      ctmp, csvd              ; ctmp = tolower(csvd)
 
129
        subi    ctmp, -(255 - 'z')      ; shift a..z to 230..255
 
130
        subi    ctmp, 255 - ('z' - 'a')
 
131
        brlo    1f                      ; branch, if not an alpha
 
132
        sez
 
133
1:      ret
 
134
 
 
135
ENDFUNC
 
136
#endif /* not __DOXYGEN__ */