Subversion Repositories Kolibri OS

Rev

Rev 2288 | Rev 6318 | 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: 2455 $
  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.