Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
9715 Doczom 3
;; Copyright (C) KolibriOS team 2004-2022. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;; Author: Kees J. Bot 1 Jan 1994                               ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 9715 $
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
6318 serge 118
        mov     ecx, [n]
2288 clevermous 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
127
@@:
128
        mov     eax, edx
129
        sub     eax, ecx         ; Compute bytes scanned
130
        pop     edi
131
        ret
132
endp
133
 
134
align 4
135
proc strchr stdcall, s:dword, c:dword
136
        push    edi
137
        cld
138
        mov     edi, [s]         ; edi = string
139
        mov     edx, 16          ; Look at small chunks of the string
140
.next:
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
157
.found:
158
        pop     eax              ; Get rid of those flags
159
        lea     eax, [edi-1]     ; Address of byte found
160
        pop     edi
161
        ret
162
 
163
endp
164
 
165
 
166
proc strrchr stdcall, s:dword, c:dword
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
183
.fail:
184
        xor     eax, eax         ; Not there
185
        pop     edi
186
        ret
187
endp
188