Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
519 serge 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
 
750 victor 8
$Revision: 889 $
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
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
889 serge 60
_strncmp@12:
519 serge 61
proc strncmp stdcall, s1:dword, s2:dword, n:dword
62
 
63
           push esi
64
           push edi
65
           mov ecx, [n]
66
           test ecx, ecx         ; Max length is zero?
67
           je .done
68
 
69
           mov esi, [s1]         ; esi = string s1
70
           mov edi, [s2]         ; edi = string s2
71
           cld
72
.compare:
73
           cmpsb                 ; Compare two bytes
74
           jne .done
75
           cmp byte [esi-1], 0   ; End of string?
76
           je .done
77
           dec ecx               ; Length limit reached?
78
           jne .compare
79
.done:
80
           seta al               ; al = (s1 > s2)
81
           setb ah               ; ah = (s1 < s2)
82
           sub al, ah
83
           movsx eax, al         ; eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1
84
           pop edi
85
           pop esi
86
           ret
87
endp
88
 
89
align 4
90
proc strncpy stdcall, s1:dword, s2:dword, n:dword
91
 
92
           push esi
93
           push edi
94
 
95
           mov ecx, [n]          ; Maximum length
96
           mov edi, [s2]         ; edi = string s2
97
           xor al, al            ; Look for a zero byte
98
           mov edx, ecx          ; Save maximum count
99
           cld
100
           repne scasb           ; Look for end of s2
101
           sub edx, ecx          ; Number of bytes in s2 including null
102
           xchg ecx, edx
103
           mov esi, [s2]         ; esi = string s2
104
           mov edi, [s1]         ; edi = string s1
105
           rep movsb             ; Copy bytes
106
 
107
           mov ecx, edx          ; Number of bytes not copied
108
           rep stosb             ; strncpy always copies n bytes by null padding
109
           mov eax, [s1]         ; Return s1
110
           pop edi
111
           pop esi
112
           ret
113
endp
114
 
115
align 4
116
proc strnlen stdcall, s:dword, n:dword
117
 
118
           push edi
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