Subversion Repositories Kolibri OS

Rev

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

  1. $Revision: 431 $
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;                                                              ;;
  4. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  5. ;; Distributed under terms of the GNU General Public License    ;;
  6. ;; Author: Kees J. Bot 1 Jan 1994                               ;;
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8.  
  9.  
  10. ; size_t strncat(char *s1, const char *s2, size_t n)
  11. ; Append string s2 to s1.
  12.  
  13. ; char *strchr(const char *s, int c)
  14.  
  15.  
  16. ; int strncmp(const char *s1, const char *s2, size_t n)
  17. ; Compare two strings.
  18.  
  19. ; char *strncpy(char *s1, const char *s2, size_t n)
  20. ; Copy string s2 to s1.
  21.  
  22. ; size_t strnlen(const char *s, size_t n)
  23. ; Return the length of a string.
  24.  
  25. ; proc strrchr stdcall, s:dword, c:dword
  26. ; Look for the last occurrence a character in a string.
  27.  
  28. proc strncat stdcall, s1:dword, s2:dword, n:dword
  29.            push esi
  30.            push edi
  31.            mov edi, [s1]         ; String s1
  32.            mov edx, [n]          ; Maximum length
  33.  
  34.            mov ecx, -1
  35.            xor al, al            ; Null byte
  36.            cld
  37.            repne scasb           ; Look for the zero byte in s1
  38.            dec edi               ; Back one up (and clear 'Z' flag)
  39.            push edi              ; Save end of s1
  40.            mov edi, [s2]         ; edi = string s2
  41.            mov ecx, edx          ; Maximum count
  42.            repne scasb           ; Look for the end of s2
  43.            jne @F
  44.            inc ecx               ; Exclude null byte
  45. @@:
  46.            sub edx, ecx          ; Number of bytes in s2
  47.            mov ecx, edx
  48.            mov esi, [s2]         ; esi = string s2
  49.            pop edi               ; edi = end of string s1
  50.            rep movsb             ; Copy bytes
  51.            stosb                 ; Add a terminating null
  52.            mov eax, [s1]         ; Return s1
  53.            pop edi
  54.            pop esi
  55.            ret
  56. endp
  57.  
  58. align 4
  59. proc strncmp stdcall, s1:dword, s2:dword, n:dword
  60.  
  61.            push esi
  62.            push edi
  63.            mov ecx, [n]
  64.            test ecx, ecx         ; Max length is zero?
  65.            je .done
  66.  
  67.            mov esi, [s1]         ; esi = string s1
  68.            mov edi, [s2]         ; edi = string s2
  69.            cld
  70. .compare:
  71.            cmpsb                 ; Compare two bytes
  72.            jne .done
  73.            cmp byte [esi-1], 0   ; End of string?
  74.            je .done
  75.            dec ecx               ; Length limit reached?
  76.            jne .compare
  77. .done:
  78.            seta al               ; al = (s1 > s2)
  79.            setb ah               ; ah = (s1 < s2)
  80.            sub al, ah
  81.            movsx eax, al         ; eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1
  82.            pop edi
  83.            pop esi
  84.            ret
  85. endp
  86.  
  87. align 4
  88. proc strncpy stdcall, s1:dword, s2:dword, n:dword
  89.  
  90.            push esi
  91.            push edi
  92.  
  93.            mov ecx, [n]          ; Maximum length
  94.            mov edi, [s2]         ; edi = string s2
  95.            xor al, al            ; Look for a zero byte
  96.            mov edx, ecx          ; Save maximum count
  97.            cld
  98.            repne scasb           ; Look for end of s2
  99.            sub edx, ecx          ; Number of bytes in s2 including null
  100.            xchg ecx, edx
  101.            mov esi, [s2]         ; esi = string s2
  102.            mov edi, [s1]         ; edi = string s1
  103.            rep movsb             ; Copy bytes
  104.  
  105.            mov ecx, edx          ; Number of bytes not copied
  106.            rep stosb             ; strncpy always copies n bytes by null padding
  107.            mov eax, [s1]         ; Return s1
  108.            pop edi
  109.            pop esi
  110.            ret
  111. endp
  112.  
  113. align 4
  114. proc strnlen stdcall, s:dword, n:dword
  115.  
  116.            push edi
  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.  
  187.  
  188.