diff lisp/cl-extra.el @ 4906:6ef8256a020a

implement equalp in C, fix case-folding, add equal() method for keymaps -------------------- ChangeLog entries follow: -------------------- lisp/ChangeLog addition: 2010-02-01 Ben Wing <ben@xemacs.org> * cl-extra.el: * cl-extra.el (cl-string-vector-equalp): Removed. * cl-extra.el (cl-bit-vector-vector-equalp): Removed. * cl-extra.el (cl-vector-array-equalp): Removed. * cl-extra.el (cl-hash-table-contents-equalp): Removed. * cl-extra.el (equalp): Removed. * cl-extra.el (cl-mapcar-many): Comment out the whole `equalp' implementation for the moment; remove once we're sure the C implementation works. * cl-macs.el: * cl-macs.el (equalp): Simplify the compiler-macro for `equalp' -- once it's in C, we don't need to try so hard to expand it. src/ChangeLog addition: 2010-02-01 Ben Wing <ben@xemacs.org> * abbrev.c (abbrev_match_mapper): * buffer.h (CANON_TABLE_OF): * buffer.h: * editfns.c (Fchar_equal): * minibuf.c (scmp_1): * text.c (qxestrcasecmp_i18n): * text.c (qxestrncasecmp_i18n): * text.c (qxetextcasecmp): * text.c (qxetextcasecmp_matching): Create new macro CANONCASE that converts to a canonical mapping and use it to do caseless comparisons instead of DOWNCASE. * alloc.c: * alloc.c (cons_equal): * alloc.c (vector_equal): * alloc.c (string_equal): * bytecode.c (compiled_function_equal): * chartab.c (char_table_entry_equal): * chartab.c (char_table_equal): * data.c (weak_list_equal): * data.c (weak_box_equal): * data.c (ephemeron_equal): * device-msw.c (equal_devmode): * elhash.c (hash_table_equal): * events.c (event_equal): * extents.c (properties_equal): * extents.c (extent_equal): * faces.c: * faces.c (face_equal): * faces.c (face_hash): * floatfns.c (float_equal): * fns.c: * fns.c (bit_vector_equal): * fns.c (plists_differ): * fns.c (Fplists_eq): * fns.c (Fplists_equal): * fns.c (Flax_plists_eq): * fns.c (Flax_plists_equal): * fns.c (internal_equal): * fns.c (internal_equalp): * fns.c (internal_equal_0): * fns.c (syms_of_fns): * glyphs.c (image_instance_equal): * glyphs.c (glyph_equal): * glyphs.c (glyph_hash): * gui.c (gui_item_equal): * lisp.h: * lrecord.h (struct lrecord_implementation): * marker.c (marker_equal): * number.c (bignum_equal): * number.c (ratio_equal): * number.c (bigfloat_equal): * objects.c (color_instance_equal): * objects.c (font_instance_equal): * opaque.c (equal_opaque): * opaque.c (equal_opaque_ptr): * rangetab.c (range_table_equal): * specifier.c (specifier_equal): Add a `foldcase' param to the equal() method and use it to implement `equalp' comparisons. Also add to plists_differ(), although we don't currently use it here. Rewrite internal_equalp(). Implement cross-type vector comparisons. Don't implement our own handling of numeric promotion -- just use the `=' primitive. Add internal_equal_0(), which takes a `foldcase' param and calls either internal_equal() or internal_equalp(). * buffer.h: When given a 0 for buffer (which is the norm when functions don't have a specific buffer available), use the current buffer's table, not `standard-case-table'; otherwise the current settings are ignored. * casetab.c: * casetab.c (set_case_table): When handling old-style vectors of 256 in `set-case-table' don't overwrite the existing table! Instead create a new table and populate. * device-msw.c (sync_printer_with_devmode): * lisp.h: * text.c (lisp_strcasecmp_ascii): Rename lisp_strcasecmp to lisp_strcasecmp_ascii and use lisp_strcasecmp_i18n for caseless comparisons in some places. * elhash.c: Delete unused lisp_string_hash and lisp_string_equal(). * events.h: * keymap-buttons.h: * keymap.h: * keymap.c (keymap_lookup_directly): * keymap.c (keymap_store): * keymap.c (FROB): * keymap.c (key_desc_list_to_event): * keymap.c (describe_map_mapper): * keymap.c (INCLUDE_BUTTON_ZERO): New file keymap-buttons.h; use to handle buttons 1-26 in place of duplicating code 26 times. * frame-gtk.c (allocate_gtk_frame_struct): * frame-msw.c (mswindows_init_frame_1): Fix some comments about internal_equal() in redisplay that don't apply any more. * keymap-slots.h: * keymap.c: New file keymap-slots.h. Use it to notate the slots in a keymap structure, similar to frameslots.h or coding-system-slots.h. * keymap.c (MARKED_SLOT): * keymap.c (keymap_equal): * keymap.c (keymap_hash): Implement. tests/ChangeLog addition: 2010-02-01 Ben Wing <ben@xemacs.org> * automated/case-tests.el: * automated/case-tests.el (uni-mappings): * automated/search-tests.el: Delete old pristine-case-table code. Rewrite the Unicode torture test to take into account whether overlapping mappings exist for more than one character, and not doing the upcase/downcase comparisons in such cases. * automated/lisp-tests.el (foo): * automated/lisp-tests.el (string-variable): * automated/lisp-tests.el (featurep): Replace Assert (equal ... with Assert-equal; same for other types of equality. Replace some awkward equivalents of Assert-equalp with Assert-equalp. Add lots of equalp tests. * automated/case-tests.el: * automated/regexp-tests.el: * automated/search-tests.el: Fix up the comments at the top of the files. Move rules about where to put tests into case-tests.el. * automated/test-harness.el: * automated/test-harness.el (test-harness-aborted-summary-template): New. * automated/test-harness.el (test-harness-from-buffer): * automated/test-harness.el (batch-test-emacs): Fix Assert-test-not. Create Assert-not-equal and variants. Delete the doc strings from all these convenience functions to avoid excessive repetition; instead use one copy in a comment.
author Ben Wing <ben@xemacs.org>
date Mon, 01 Feb 2010 01:02:40 -0600
parents b828e06dbe38
children c17c857e20bf
line wrap: on
line diff
--- a/lisp/cl-extra.el	Sat Jan 30 20:34:23 2010 -0600
+++ b/lisp/cl-extra.el	Mon Feb 01 01:02:40 2010 -0600
@@ -87,130 +87,130 @@
 	(t (error "Can't coerce %s to type %s" x type))))
 
 
-;;; Predicates.
-
-;; I'd actually prefer not to have this inline, the space
-;; vs. amount-it's-called trade-off isn't reasonable, but that would
-;; introduce bytecode problems with the compiler macro in cl-macs.el.
-(defsubst cl-string-vector-equalp (cl-string cl-vector)
-  "Helper function for `equalp', which see."
-;  (check-argument-type #'stringp cl-string)
-;  (check-argument-type #'vector cl-vector)
-  (let ((cl-i (length cl-string))
-	cl-char cl-other)
-    (when (= cl-i (length cl-vector))
-      (while (and (>= (setq cl-i (1- cl-i)) 0)
-		  (or (eq (setq cl-char (aref cl-string cl-i))
-			  (setq cl-other (aref cl-vector cl-i)))
-		      (and (characterp cl-other) ; Note we want to call this
-						 ; as rarely as possible, it
-						 ; doesn't have a bytecode.
-			   (eq (downcase cl-char) (downcase cl-other))))))
-      (< cl-i 0))))
-
-;; See comment on cl-string-vector-equalp above.
-(defsubst cl-bit-vector-vector-equalp (cl-bit-vector cl-vector)
-  "Helper function for `equalp', which see."
-;  (check-argument-type #'bit-vector-p cl-bit-vector)
-;  (check-argument-type #'vectorp cl-vector)
-  (let ((cl-i (length cl-bit-vector))
-	cl-other)
-    (when (= cl-i (length cl-vector))
-      (while (and (>= (setq cl-i (1- cl-i)) 0)
-		  (numberp (setq cl-other (aref cl-vector cl-i)))
-		  ;; Differs from clisp here.
-		  (= (aref cl-bit-vector cl-i) cl-other)))
-      (< cl-i 0))))
-
-;; These two helper functions call equalp recursively, the two above have no
-;; need to.
-(defsubst cl-vector-array-equalp (cl-vector cl-array)
-  "Helper function for `equalp', which see."
-;  (check-argument-type #'vector cl-vector)
-;  (check-argument-type #'arrayp cl-array)
-  (let ((cl-i (length cl-vector)))
-    (when (= cl-i (length cl-array))
-      (while (and (>= (setq cl-i (1- cl-i)) 0)
-		  (equalp (aref cl-vector cl-i) (aref cl-array cl-i))))
-      (< cl-i 0))))
-
-(defsubst cl-hash-table-contents-equalp (cl-hash-table-1 cl-hash-table-2)
-  "Helper function for `equalp', which see."
-  (symbol-macrolet
-      ;; If someone has gone and fished the uninterned symbol out of this
-      ;; function's constants vector, and subsequently stored it as a value
-      ;; in a hash table, it's their own damn fault when
-      ;; `cl-hash-table-contents-equalp' gives the wrong answer.
-      ((equalp-default '#:equalp-default))
-    (loop
-      for x-key being the hash-key in cl-hash-table-1
-      using (hash-value x-value)
-      with y-value = nil
-      always (and (not (eq equalp-default
-			   (setq y-value (gethash x-key cl-hash-table-2
-						  equalp-default))))
-		  (equalp y-value x-value)))))
-
-(defun equalp (x y)
-  "Return t if two Lisp objects have similar structures and contents.
-
-This is like `equal', except that it accepts numerically equal
-numbers of different types (float, integer, bignum, bigfloat), and also
-compares strings and characters case-insensitively.
-
-Arrays (that is, strings, bit-vectors, and vectors) of the same length and
-with contents that are `equalp' are themselves `equalp'.
-
-Two hash tables are `equalp' if they have the same test (see
-`hash-table-test'), if they have the same number of entries, and if, for
-each entry in one hash table, its key is equivalent to a key in the other
-hash table using the hash table test, and its value is `equalp' to the other
-hash table's value for that key."
-  (cond ((eq x y))
-	((stringp x)
-	 (if (stringp y)
-	     (eq t (compare-strings x nil nil y nil nil t))
-	   (if (vectorp y)
-	       (cl-string-vector-equalp x y)
-	     ;; bit-vectors and strings are only equalp if they're
-	     ;; zero-length:
-	     (and (equal "" x) (equal #* y)))))
-	((numberp x)
-	 (and (numberp y) (= x y)))
-	((consp x)
-	 (while (and (consp x) (consp y) (equalp (car x) (car y)))
-	   (setq x (cdr x) y (cdr y)))
-	 (and (not (consp x)) (equalp x y)))
-	(t
-	 ;; From here on, the type tests don't (yet) have bytecodes.
-	 (let ((x-type (type-of x)))
-	   (cond ((eq 'vector x-type)
-		  (if (stringp y)
-		      (cl-string-vector-equalp y x)
-		    (if (vectorp y)
-			(cl-vector-array-equalp x y)
-		      (if (bit-vector-p y)
-			  (cl-bit-vector-vector-equalp y x)))))
-		 ((eq 'character x-type)
-		  (and (characterp y)
-		       ;; If the characters are actually identical, the
-		       ;; first eq test will have caught them above; we only
-		       ;; need to check them case-insensitively here.
-		       (eq (downcase x) (downcase y))))
-		 ((eq 'hash-table x-type)
-		  (and (hash-table-p y)
-		       (eq (hash-table-test x) (hash-table-test y))
-		       (= (hash-table-count x) (hash-table-count y))
-		       (cl-hash-table-contents-equalp x y)))
-		 ((eq 'bit-vector x-type)
-		  (if (bit-vector-p y)
-		      (equal x y)
-		    (if (vectorp y)
-			(cl-bit-vector-vector-equalp x y)
-		      ;; bit-vectors and strings are only equalp if they're
-		      ;; zero-length:
-		      (and (equal "" y) (equal #* x)))))
-		 (t (equal x y)))))))
+;;;;; Predicates.
+;;
+;;;; I'd actually prefer not to have this inline, the space
+;;;; vs. amount-it's-called trade-off isn't reasonable, but that would
+;;;; introduce bytecode problems with the compiler macro in cl-macs.el.
+;;(defsubst cl-string-vector-equalp (cl-string cl-vector)
+;;  "Helper function for `equalp', which see."
+;;;  (check-argument-type #'stringp cl-string)
+;;;  (check-argument-type #'vector cl-vector)
+;;  (let ((cl-i (length cl-string))
+;;	cl-char cl-other)
+;;    (when (= cl-i (length cl-vector))
+;;      (while (and (>= (setq cl-i (1- cl-i)) 0)
+;;		  (or (eq (setq cl-char (aref cl-string cl-i))
+;;			  (setq cl-other (aref cl-vector cl-i)))
+;;		      (and (characterp cl-other) ; Note we want to call this
+;;						 ; as rarely as possible, it
+;;						 ; doesn't have a bytecode.
+;;			   (eq (downcase cl-char) (downcase cl-other))))))
+;;      (< cl-i 0))))
+;;
+;;;; See comment on cl-string-vector-equalp above.
+;;(defsubst cl-bit-vector-vector-equalp (cl-bit-vector cl-vector)
+;;  "Helper function for `equalp', which see."
+;;;  (check-argument-type #'bit-vector-p cl-bit-vector)
+;;;  (check-argument-type #'vectorp cl-vector)
+;;  (let ((cl-i (length cl-bit-vector))
+;;	cl-other)
+;;    (when (= cl-i (length cl-vector))
+;;      (while (and (>= (setq cl-i (1- cl-i)) 0)
+;;		  (numberp (setq cl-other (aref cl-vector cl-i)))
+;;		  ;; Differs from clisp here.
+;;		  (= (aref cl-bit-vector cl-i) cl-other)))
+;;      (< cl-i 0))))
+;;
+;;;; These two helper functions call equalp recursively, the two above have no
+;;;; need to.
+;;(defsubst cl-vector-array-equalp (cl-vector cl-array)
+;;  "Helper function for `equalp', which see."
+;;;  (check-argument-type #'vector cl-vector)
+;;;  (check-argument-type #'arrayp cl-array)
+;;  (let ((cl-i (length cl-vector)))
+;;    (when (= cl-i (length cl-array))
+;;      (while (and (>= (setq cl-i (1- cl-i)) 0)
+;;		  (equalp (aref cl-vector cl-i) (aref cl-array cl-i))))
+;;      (< cl-i 0))))
+;;
+;;(defsubst cl-hash-table-contents-equalp (cl-hash-table-1 cl-hash-table-2)
+;;  "Helper function for `equalp', which see."
+;;  (symbol-macrolet
+;;      ;; If someone has gone and fished the uninterned symbol out of this
+;;      ;; function's constants vector, and subsequently stored it as a value
+;;      ;; in a hash table, it's their own damn fault when
+;;      ;; `cl-hash-table-contents-equalp' gives the wrong answer.
+;;      ((equalp-default '#:equalp-default))
+;;    (loop
+;;      for x-key being the hash-key in cl-hash-table-1
+;;      using (hash-value x-value)
+;;      with y-value = nil
+;;      always (and (not (eq equalp-default
+;;			   (setq y-value (gethash x-key cl-hash-table-2
+;;						  equalp-default))))
+;;		  (equalp y-value x-value)))))
+;;
+;;(defun equalp (x y)
+;;  "Return t if two Lisp objects have similar structures and contents.
+;;
+;;This is like `equal', except that it accepts numerically equal
+;;numbers of different types (float, integer, bignum, bigfloat), and also
+;;compares strings and characters case-insensitively.
+;;
+;;Arrays (that is, strings, bit-vectors, and vectors) of the same length and
+;;with contents that are `equalp' are themselves `equalp'.
+;;
+;;Two hash tables are `equalp' if they have the same test (see
+;;`hash-table-test'), if they have the same number of entries, and if, for
+;;each entry in one hash table, its key is equivalent to a key in the other
+;;hash table using the hash table test, and its value is `equalp' to the other
+;;hash table's value for that key."
+;;  (cond ((eq x y))
+;;	((stringp x)
+;;	 (if (stringp y)
+;;	     (eq t (compare-strings x nil nil y nil nil t))
+;;	   (if (vectorp y)
+;;	       (cl-string-vector-equalp x y)
+;;	     ;; bit-vectors and strings are only equalp if they're
+;;	     ;; zero-length:
+;;	     (and (equal "" x) (equal #* y)))))
+;;	((numberp x)
+;;	 (and (numberp y) (= x y)))
+;;	((consp x)
+;;	 (while (and (consp x) (consp y) (equalp (car x) (car y)))
+;;	   (setq x (cdr x) y (cdr y)))
+;;	 (and (not (consp x)) (equalp x y)))
+;;	(t
+;;	 ;; From here on, the type tests don't (yet) have bytecodes.
+;;	 (let ((x-type (type-of x)))
+;;	   (cond ((eq 'vector x-type)
+;;		  (if (stringp y)
+;;		      (cl-string-vector-equalp y x)
+;;		    (if (vectorp y)
+;;			(cl-vector-array-equalp x y)
+;;		      (if (bit-vector-p y)
+;;			  (cl-bit-vector-vector-equalp y x)))))
+;;		 ((eq 'character x-type)
+;;		  (and (characterp y)
+;;		       ;; If the characters are actually identical, the
+;;		       ;; first eq test will have caught them above; we only
+;;		       ;; need to check them case-insensitively here.
+;;		       (eq (downcase x) (downcase y))))
+;;		 ((eq 'hash-table x-type)
+;;		  (and (hash-table-p y)
+;;		       (eq (hash-table-test x) (hash-table-test y))
+;;		       (= (hash-table-count x) (hash-table-count y))
+;;		       (cl-hash-table-contents-equalp x y)))
+;;		 ((eq 'bit-vector x-type)
+;;		  (if (bit-vector-p y)
+;;		      (equal x y)
+;;		    (if (vectorp y)
+;;			(cl-bit-vector-vector-equalp x y)
+;;		      ;; bit-vectors and strings are only equalp if they're
+;;		      ;; zero-length:
+;;		      (and (equal "" y) (equal #* x)))))
+;;		 (t (equal x y)))))))
 
 ;;; Control structures.