~ chicken-core (chicken-5) 1be37b85437c8e0644964ed6ca7b54a1ecfd29b5


commit 1be37b85437c8e0644964ed6ca7b54a1ecfd29b5
Author:     Jim Ursetto <zbigniewsz@gmail.com>
AuthorDate: Mon Apr 23 12:56:22 2012 -0500
Commit:     Peter Bex <peter.bex@xs4all.nl>
CommitDate: Mon Apr 23 20:04:33 2012 +0200

    Also use C_memcasecmp for case-insensitive substring comparisons (#808)
    
    Signed-off-by: Peter Bex <peter.bex@xs4all.nl>

diff --git a/chicken.h b/chicken.h
index 3854c0c0..837a51cf 100644
--- a/chicken.h
+++ b/chicken.h
@@ -1118,7 +1118,7 @@ extern double trunc(double);
                                                            (C_char *)C_data_pointer(s2) + C_unfix(start2), \
                                                            C_unfix(len) ) == 0)
 #define C_substring_compare_case_insensitive(s1, s2, start1, start2, len) \
-                                        C_mk_bool(C_strncasecmp((C_char *)C_data_pointer(s1) + C_unfix(start1), \
+                                        C_mk_bool(C_memcasecmp((C_char *)C_data_pointer(s1) + C_unfix(start1), \
                                                                 (C_char *)C_data_pointer(s2) + C_unfix(start2), \
                                                                 C_unfix(len) ) == 0)
 /* this does not use C_mutate: */
@@ -2112,12 +2112,10 @@ C_inline int C_memcasecmp(const char *x, const char *y, unsigned int len)
   const unsigned char *ux = (const unsigned char *)x;
   const unsigned char *uy = (const unsigned char *)y;
 
-  if (len == 0) return 0;
-  
-  do {
+  while (len--) {
     if (tolower(*ux++) != tolower(*uy++))
       return (tolower(*--ux) - tolower(*--uy));
-  } while(--len != 0);
+  }
   return 0;
 }
 
diff --git a/data-structures.scm b/data-structures.scm
index 058bc511..2ed9102a 100644
--- a/data-structures.scm
+++ b/data-structures.scm
@@ -26,11 +26,7 @@
 
 
 (declare
- (unit data-structures)
- (foreign-declare #<<EOF
-#define C_mem_compare(to, from, n)   C_fix(C_memcmp(C_c_string(to), C_c_string(from), C_unfix(n)))
-EOF
-) )
+ (unit data-structures))
 
 (include "common-declarations.scm")
 
@@ -352,7 +348,7 @@ EOF
   (let ((len1 (##sys#size s1))
 	(len2 (##sys#size s2)) )
     (let* ((len-diff (fx- len1 len2)) 
-	   (cmp (##core#inline "C_mem_compare" s1 s2 (if (fx< len-diff 0) len1 len2))))
+	   (cmp (##core#inline "C_string_compare" s1 s2 (if (fx< len-diff 0) len1 len2))))
       (if (fx= cmp 0) 
 	  len-diff 
 	  cmp))))
diff --git a/tests/data-structures-tests.scm b/tests/data-structures-tests.scm
index df4b5591..b0f8794b 100644
--- a/tests/data-structures-tests.scm
+++ b/tests/data-structures-tests.scm
@@ -1,6 +1,5 @@
 ;;;; data-structures-tests.scm
 
-
 (use data-structures)
 
 (let ((alist '((foo . 123) ("bar" . "baz"))))
@@ -15,4 +14,26 @@
   (alist-update 'foo 999 alist)
   (assert (= (alist-ref 'foo alist) 123))
   (assert (eq? 'yep (alist-ref 'qux (alist-update 'qux 'yep alist))))
-  (assert (eq? 'ok (alist-ref "bar" (alist-update "bar" 'ok alist equal?) equal?))))
\ No newline at end of file
+  (assert (eq? 'ok (alist-ref "bar" (alist-update "bar" 'ok alist equal?) equal?))))
+
+;; #808: strings with embedded nul bytes should not be compared
+;; with ASCIIZ string comparison functions
+(assert (substring=? "foo\x00a" "foo\x00a" 1 1))
+(assert (substring-ci=? "foo\x00a" "foo\x00a" 1 1))
+(assert (substring-ci=? "foo\x00a" "foo\x00A" 1 1))
+(assert (= 2 (substring-index "o\x00bar" "foo\x00bar")))
+(assert (= 2 (substring-index-ci "o\x00bar" "foo\x00bar")))
+(assert (= 2 (substring-index-ci "o\x00bar" "foo\x00BAR")))
+(assert (not (substring=? "foo\x00a" "foo\x00b" 1 1)))
+(assert (not (substring-ci=? "foo\x00a" "foo\x00b" 1 1)))
+(assert (not (substring-index "o\x00bar" "foo\x00baz")))
+(assert (not (substring-index-ci "o\x00bar" "foo\x00baz")))
+(assert (= 0 (string-compare3 "foo\x00a" "foo\x00a")))
+(assert (> 0 (string-compare3 "foo\x00a" "foo\x00b")))
+(assert (< 0 (string-compare3 "foo\x00b" "foo\x00a")))
+(assert (= 0 (string-compare3-ci "foo\x00a" "foo\x00a")))
+(assert (= 0 (string-compare3-ci "foo\x00a" "foo\x00A")))
+(assert (> 0 (string-compare3-ci "foo\x00a" "foo\x00b")))
+(assert (> 0 (string-compare3-ci "foo\x00A" "foo\x00b")))
+(assert (< 0 (string-compare3-ci "foo\x00b" "foo\x00a")))
+(assert (< 0 (string-compare3-ci "foo\x00b" "foo\x00A")))
diff --git a/tests/library-tests.scm b/tests/library-tests.scm
index f9cb61d2..a7c17e51 100644
--- a/tests/library-tests.scm
+++ b/tests/library-tests.scm
@@ -220,8 +220,14 @@
 (assert (equal? '#${abc} '#${ab0c}))
 (assert (equal? '#${a b c} '#${0a0b0c}))
 
-;; #800: blobs and strings with embedded nul bytes should not be compared
+;; #808: blobs and strings with embedded nul bytes should not be compared
 ;; with ASCIIZ string comparison functions
+(assert (equal? '#${a b 0 c} '#${a b 0 c}))
+(assert (blob=? '#${a b 0 c} '#${a b 0 c}))
+(assert (equal=? "foo\x00a" "foo\x00a"))
+(assert (string=? "foo\x00a" "foo\x00a"))
+(assert (string-ci=? "foo\x00a" "foo\x00a"))
+(assert (string-ci=? "foo\x00a" "foo\x00A"))
 (assert (not (equal? '#${a b 0 c} '#${a b 0 d})))
 (assert (not (blob=? '#${a b 0 c} '#${a b 0 d})))
 (assert (not (equal=? "foo\x00a" "foo\x00b")))
Trap