Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1159 hidnplayr 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
 
1206 hidnplayr 8
$Revision: 1206 $
1159 hidnplayr 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
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
126
@@:
127
           mov eax, edx
128
           sub eax, ecx          ; Compute bytes scanned
129
           pop edi
130
           ret
131
endp
132
 
133
align 4
134
proc strchr stdcall, s:dword, c:dword
135
           push edi
136
           cld
137
           mov edi, [s]          ; edi = string
138
           mov edx, 16           ; Look at small chunks of the string
139
.next:
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
156
.found:
157
           pop eax               ; Get rid of those flags
158
           lea eax, [edi-1]      ; Address of byte found
159
           pop edi
160
           ret
161
 
162
endp
163
 
164
 
165
proc strrchr stdcall, s:dword, c:dword
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
182
.fail:
183
           xor eax, eax          ; Not there
184
           pop edi
185
           ret
186
endp
187