Rev 2455 | Rev 9715 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2288 | clevermous | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
5363 | yogev_ezra | 3 | ;; Copyright (C) KolibriOS team 2004-2015. 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: 5363 $ |
||
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 |