;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; Author: Kees J. Bot 1 Jan 1994 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; $Revision: 5565 $ ; size_t strncat(char *s1, const char *s2, size_t n) ; Append string s2 to s1. ; char *strchr(const char *s, int c) ; int strncmp(const char *s1, const char *s2, size_t n) ; Compare two strings. ; char *strncpy(char *s1, const char *s2, size_t n) ; Copy string s2 to s1. ; size_t strnlen(const char *s, size_t n) ; Return the length of a string. ; proc strrchr stdcall, s:dword, c:dword ; Look for the last occurrence a character in a string. proc strncat stdcall, s1:dword, s2:dword, n:dword push esi push edi mov edi, [s1] ; String s1 mov edx, [n] ; Maximum length mov ecx, -1 xor al, al ; Null byte cld repne scasb ; Look for the zero byte in s1 dec edi ; Back one up (and clear 'Z' flag) push edi ; Save end of s1 mov edi, [s2] ; edi = string s2 mov ecx, edx ; Maximum count repne scasb ; Look for the end of s2 jne @F inc ecx ; Exclude null byte @@: sub edx, ecx ; Number of bytes in s2 mov ecx, edx mov esi, [s2] ; esi = string s2 pop edi ; edi = end of string s1 rep movsb ; Copy bytes stosb ; Add a terminating null mov eax, [s1] ; Return s1 pop edi pop esi ret endp align 4 proc strncmp stdcall, s1:dword, s2:dword, n:dword push esi push edi mov ecx, [n] test ecx, ecx ; Max length is zero? je .done mov esi, [s1] ; esi = string s1 mov edi, [s2] ; edi = string s2 cld .compare: cmpsb ; Compare two bytes jne .done cmp byte [esi-1], 0 ; End of string? je .done dec ecx ; Length limit reached? jne .compare .done: seta al ; al = (s1 > s2) setb ah ; ah = (s1 < s2) sub al, ah movsx eax, al ; eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1 pop edi pop esi ret endp align 4 proc strncpy stdcall, s1:dword, s2:dword, n:dword push esi push edi mov ecx, [n] ; Maximum length mov edi, [s2] ; edi = string s2 xor al, al ; Look for a zero byte mov edx, ecx ; Save maximum count cld repne scasb ; Look for end of s2 sub edx, ecx ; Number of bytes in s2 including null xchg ecx, edx mov esi, [s2] ; esi = string s2 mov edi, [s1] ; edi = string s1 rep movsb ; Copy bytes mov ecx, edx ; Number of bytes not copied rep stosb ; strncpy always copies n bytes by null padding mov eax, [s1] ; Return s1 pop edi pop esi ret endp align 4 proc strnlen stdcall, s:dword, n:dword push edi mov edi, [s] ; edi = string xor al, al ; Look for a zero byte mov edx, ecx ; Save maximum count cmp cl, 1 ; 'Z' bit must be clear if ecx = 0 cld repne scasb ; Look for zero jne @F inc ecx ; Don't count zero byte @@: mov eax, edx sub eax, ecx ; Compute bytes scanned pop edi ret endp align 4 proc strchr stdcall, s:dword, c:dword push edi cld mov edi, [s] ; edi = string mov edx, 16 ; Look at small chunks of the string .next: shl edx, 1 ; Chunks become bigger each time mov ecx, edx xor al, al ; Look for the zero at the end repne scasb pushf ; Remember the flags sub ecx, edx neg ecx ; Some or all of the chunk sub edi, ecx ; Step back mov eax, [c] ; The character to look for repne scasb je .found popf ; Did we find the end of string earlier? jne .next ; No, try again xor eax, eax ; Return NULL pop edi ret .found: pop eax ; Get rid of those flags lea eax, [edi-1] ; Address of byte found pop edi ret endp proc strrchr stdcall, s:dword, c:dword push edi mov edi, [s] ; edi = string mov ecx, -1 xor al, al cld repne scasb ; Look for the end of the string not ecx ; -1 - ecx = Length of the string + null dec edi ; Put edi back on the zero byte mov eax, [c] ; The character to look for std ; Downwards search repne scasb cld ; Direction bit back to default jne .fail lea eax, [edi+1] ; Found it pop edi ret .fail: xor eax, eax ; Not there pop edi ret endp