Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
519 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2465 Serge 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
519 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;; Author: Kees J. Bot 1 Jan 1994                               ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
750 victor 8
$Revision: 3908 $
519 serge 9
 
593 mikedld 10
 
519 serge 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
3908 Serge 30
        push    esi
31
        push    edi
32
        mov     edi, [s1]        ; String s1
33
        mov     edx, [n]         ; Maximum length
519 serge 34
 
3908 Serge 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
519 serge 46
@@:
3908 Serge 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
519 serge 57
endp
58
 
59
align 4
60
proc strncmp stdcall, s1:dword, s2:dword, n:dword
61
 
3908 Serge 62
        push    esi
63
        push    edi
64
        mov     ecx, [n]
65
        test    ecx, ecx         ; Max length is zero?
66
        je      .done
519 serge 67
 
3908 Serge 68
        mov     esi, [s1]        ; esi = string s1
69
        mov     edi, [s2]        ; edi = string s2
70
        cld
519 serge 71
.compare:
3908 Serge 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
519 serge 78
.done:
3908 Serge 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
519 serge 86
endp
87
 
88
align 4
89
proc strncpy stdcall, s1:dword, s2:dword, n:dword
90
 
3908 Serge 91
        push    esi
92
        push    edi
519 serge 93
 
3908 Serge 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
519 serge 105
 
3908 Serge 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
519 serge 112
endp
113
 
114
align 4
115
proc strnlen stdcall, s:dword, n:dword
116
 
3908 Serge 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
519 serge 126
@@:
3908 Serge 127
        mov     eax, edx
128
        sub     eax, ecx         ; Compute bytes scanned
129
        pop     edi
130
        ret
519 serge 131
endp
132
 
133
align 4
134
proc strchr stdcall, s:dword, c:dword
3908 Serge 135
        push    edi
136
        cld
137
        mov     edi, [s]         ; edi = string
138
        mov     edx, 16          ; Look at small chunks of the string
519 serge 139
.next:
3908 Serge 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
519 serge 156
.found:
3908 Serge 157
        pop     eax              ; Get rid of those flags
158
        lea     eax, [edi-1]     ; Address of byte found
159
        pop     edi
160
        ret
519 serge 161
 
162
endp
163
 
164
 
165
proc strrchr stdcall, s:dword, c:dword
3908 Serge 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
519 serge 182
.fail:
3908 Serge 183
        xor     eax, eax         ; Not there
184
        pop     edi
185
        ret
519 serge 186
endp
187