Subversion Repositories Kolibri OS

Rev

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

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