Subversion Repositories Kolibri OS

Rev

Rev 1635 | Rev 3908 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;; Author: Kees J. Bot 1 Jan 1994                               ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 2465 $
  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.  
  188.  
  189.