Subversion Repositories Kolibri OS

Rev

Rev 750 | Rev 2455 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;; Author: Kees J. Bot 1 Jan 1994                               ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 2288 $
9
 
10
 
11
; size_t strncat(char *s1, const char *s2, size_t n)
12
; Append string s2 to s1.
13
 
14
; char *strchr(const char *s, int c)
15
 
16
 
17
; int strncmp(const char *s1, const char *s2, size_t n)
18
; Compare two strings.
19
 
20
; char *strncpy(char *s1, const char *s2, size_t n)
21
; Copy string s2 to s1.
22
 
23
; size_t strnlen(const char *s, size_t n)
24
; Return the length of a string.
25
 
26
; proc strrchr stdcall, s:dword, c:dword
27
; Look for the last occurrence a character in a string.
28
 
29
proc strncat stdcall, s1:dword, s2:dword, n:dword
30
        push    esi
31
        push    edi
32
        mov     edi, [s1]        ; String s1
33
        mov     edx, [n]         ; Maximum length
34
 
35
        mov     ecx, -1
36
        xor     al, al           ; Null byte
37
        cld
38
        repne scasb              ; Look for the zero byte in s1
39
        dec     edi              ; Back one up (and clear 'Z' flag)
40
        push    edi              ; Save end of s1
41
        mov     edi, [s2]        ; edi = string s2
42
        mov     ecx, edx         ; Maximum count
43
        repne scasb              ; Look for the end of s2
44
        jne     @F
45
        inc     ecx              ; Exclude null byte
46
@@:
47
        sub     edx, ecx         ; Number of bytes in s2
48
        mov     ecx, edx
49
        mov     esi, [s2]        ; esi = string s2
50
        pop     edi              ; edi = end of string s1
51
        rep movsb                ; Copy bytes
52
        stosb                    ; Add a terminating null
53
        mov     eax, [s1]        ; Return s1
54
        pop     edi
55
        pop     esi
56
        ret
57
endp
58
 
59
align 4
60
proc strncmp stdcall, s1:dword, s2:dword, n:dword
61
 
62
        push    esi
63
        push    edi
64
        mov     ecx, [n]
65
        test    ecx, ecx         ; Max length is zero?
66
        je      .done
67
 
68
        mov     esi, [s1]        ; esi = string s1
69
        mov     edi, [s2]        ; edi = string s2
70
        cld
71
.compare:
72
        cmpsb                    ; Compare two bytes
73
        jne     .done
74
        cmp     byte [esi-1], 0  ; End of string?
75
        je      .done
76
        dec     ecx              ; Length limit reached?
77
        jne     .compare
78
.done:
79
        seta    al               ; al = (s1 > s2)
80
        setb    ah               ; ah = (s1 < s2)
81
        sub     al, ah
82
        movsx   eax, al          ; eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1
83
        pop     edi
84
        pop     esi
85
        ret
86
endp
87
 
88
align 4
89
proc strncpy stdcall, s1:dword, s2:dword, n:dword
90
 
91
        push    esi
92
        push    edi
93
 
94
        mov     ecx, [n]         ; Maximum length
95
        mov     edi, [s2]        ; edi = string s2
96
        xor     al, al           ; Look for a zero byte
97
        mov     edx, ecx         ; Save maximum count
98
        cld
99
        repne scasb              ; Look for end of s2
100
        sub     edx, ecx         ; Number of bytes in s2 including null
101
        xchg    ecx, edx
102
        mov     esi, [s2]        ; esi = string s2
103
        mov     edi, [s1]        ; edi = string s1
104
        rep movsb                ; Copy bytes
105
 
106
        mov     ecx, edx         ; Number of bytes not copied
107
        rep stosb                ; strncpy always copies n bytes by null padding
108
        mov     eax, [s1]        ; Return s1
109
        pop     edi
110
        pop     esi
111
        ret
112
endp
113
 
114
align 4
115
proc strnlen stdcall, s:dword, n:dword
116
 
117
        push    edi
118
        mov     edi, [s]         ; edi = string
119
        xor     al, al           ; Look for a zero byte
120
        mov     edx, ecx         ; Save maximum count
121
        cmp     cl, 1            ; 'Z' bit must be clear if ecx = 0
122
        cld
123
        repne scasb              ; Look for zero
124
        jne     @F
125
        inc     ecx              ; Don't count zero byte
126
@@:
127
        mov     eax, edx
128
        sub     eax, ecx         ; Compute bytes scanned
129
        pop     edi
130
        ret
131
endp
132
 
133
align 4
134
proc strchr stdcall, s:dword, c:dword
135
        push    edi
136
        cld
137
        mov     edi, [s]         ; edi = string
138
        mov     edx, 16          ; Look at small chunks of the string
139
.next:
140
        shl     edx, 1           ; Chunks become bigger each time
141
        mov     ecx, edx
142
        xor     al, al           ; Look for the zero at the end
143
        repne scasb
144
        pushf                    ; Remember the flags
145
        sub     ecx, edx
146
        neg     ecx              ; Some or all of the chunk
147
        sub     edi, ecx         ; Step back
148
        mov     eax, [c]         ; The character to look for
149
        repne scasb
150
        je      .found
151
        popf                     ; Did we find the end of string earlier?
152
        jne     .next            ; No, try again
153
        xor     eax, eax         ; Return NULL
154
        pop     edi
155
        ret
156
.found:
157
        pop     eax              ; Get rid of those flags
158
        lea     eax, [edi-1]     ; Address of byte found
159
        pop     edi
160
        ret
161
 
162
endp
163
 
164
 
165
proc strrchr stdcall, s:dword, c:dword
166
        push    edi
167
        mov     edi, [s]     ; edi = string
168
        mov     ecx, -1
169
        xor     al, al
170
        cld
171
        repne scasb              ; Look for the end of the string
172
        not     ecx              ; -1 - ecx = Length of the string + null
173
        dec     edi              ; Put edi back on the zero byte
174
        mov     eax, [c]         ; The character to look for
175
        std                      ; Downwards search
176
        repne scasb
177
        cld                      ; Direction bit back to default
178
        jne     .fail
179
        lea     eax, [edi+1]     ; Found it
180
        pop     edi
181
        ret
182
.fail:
183
        xor     eax, eax         ; Not there
184
        pop     edi
185
        ret
186
endp
187