Subversion Repositories Kolibri OS

Rev

Rev 5565 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
519 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
5565 serge 3
;; Copyright (C) KolibriOS team 2004-2015. 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: 6317 $
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
6317 serge 118
        mov     ecx, [n]
3908 Serge 119
        mov     edi, [s]         ; edi = string
120
        xor     al, al           ; Look for a zero byte
121
        mov     edx, ecx         ; Save maximum count
122
        cmp     cl, 1            ; 'Z' bit must be clear if ecx = 0
123
        cld
124
        repne scasb              ; Look for zero
125
        jne     @F
126
        inc     ecx              ; Don't count zero byte
519 serge 127
@@:
3908 Serge 128
        mov     eax, edx
129
        sub     eax, ecx         ; Compute bytes scanned
130
        pop     edi
131
        ret
519 serge 132
endp
133
 
134
align 4
135
proc strchr stdcall, s:dword, c:dword
3908 Serge 136
        push    edi
137
        cld
138
        mov     edi, [s]         ; edi = string
139
        mov     edx, 16          ; Look at small chunks of the string
519 serge 140
.next:
3908 Serge 141
        shl     edx, 1           ; Chunks become bigger each time
142
        mov     ecx, edx
143
        xor     al, al           ; Look for the zero at the end
144
        repne scasb
145
        pushf                    ; Remember the flags
146
        sub     ecx, edx
147
        neg     ecx              ; Some or all of the chunk
148
        sub     edi, ecx         ; Step back
149
        mov     eax, [c]         ; The character to look for
150
        repne scasb
151
        je      .found
152
        popf                     ; Did we find the end of string earlier?
153
        jne     .next            ; No, try again
154
        xor     eax, eax         ; Return NULL
155
        pop     edi
156
        ret
519 serge 157
.found:
3908 Serge 158
        pop     eax              ; Get rid of those flags
159
        lea     eax, [edi-1]     ; Address of byte found
160
        pop     edi
161
        ret
519 serge 162
 
163
endp
164
 
165
 
166
proc strrchr stdcall, s:dword, c:dword
3908 Serge 167
        push    edi
168
        mov     edi, [s]     ; edi = string
169
        mov     ecx, -1
170
        xor     al, al
171
        cld
172
        repne scasb              ; Look for the end of the string
173
        not     ecx              ; -1 - ecx = Length of the string + null
174
        dec     edi              ; Put edi back on the zero byte
175
        mov     eax, [c]         ; The character to look for
176
        std                      ; Downwards search
177
        repne scasb
178
        cld                      ; Direction bit back to default
179
        jne     .fail
180
        lea     eax, [edi+1]     ; Found it
181
        pop     edi
182
        ret
519 serge 183
.fail:
3908 Serge 184
        xor     eax, eax         ; Not there
185
        pop     edi
186
        ret
519 serge 187
endp
188