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 |