comparison src/keymap.c @ 5182:2e528066e2fc

Move #'sort*, #'fill, #'merge to C from cl-seq.el. lisp/ChangeLog addition: 2010-04-01 Aidan Kehoe <kehoea@parhasard.net> * cl-seq.el (fill, sort*, merge): Move these functions to fns.c. (stable-sort): Make this docstring reflect the argument names used in the #'sort* docstring. * cl-macs.el (stable-sort): Make #'stable-sort exactly equivalent to #'sort* in compiled code. * bytecomp.el (byte-compile-maybe-add-*): New macro, for functions like #'sort and #'mapcar that, to be strictly compatible, should only take two args, but in our implementation can take more, because they're aliases of #'sort* and #'mapcar*. (byte-compile-mapcar, byte-compile-sort, byte-compile-fillarray): Use this new macro. (map-into): Add a byte-compile method for #'map-into in passing. * apropos.el (apropos-print): Use #'sort* with a :key argument, now it's in C. * compat.el (extent-at): Ditto. * register.el (list-registers): Ditto. * package-ui.el (pui-list-packages): Ditto. * help.el (sorted-key-descriptions): Ditto. src/ChangeLog addition: 2010-03-31 Aidan Kehoe <kehoea@parhasard.net> * fns.c (STRING_DATA_TO_OBJECT_ARRAY) (BIT_VECTOR_TO_OBJECT_ARRAY, c_merge_predicate_key) (c_merge_predicate_nokey, list_merge, array_merge) (list_array_merge_into_list, list_list_merge_into_array) (list_array_merge_into_array, CHECK_KEY_ARGUMENT, Fmerge) (list_sort, array_sort, FsortX): Move #'sort*, #'fill, #'merge from cl-seq.el to C, extending the implementations of Fsort, Ffillarray, and merge() to do so. * keymap.c (keymap_submaps, map_keymap_sort_predicate) (describe_map_sort_predicate): Change the calling semantics of the C sort predicates to return a non-nil Lisp object if the first argument is less than the second, rather than C integers. * fontcolor-msw.c (sort_font_list_function): * fileio.c (build_annotations): * dired.c (Fdirectory_files): * abbrev.c (Finsert_abbrev_table_description): Call list_sort instead of Fsort, list_merge instead of merge() in these functions. man/ChangeLog addition: 2010-04-01 Aidan Kehoe <kehoea@parhasard.net> * lispref/lists.texi (Rearrangement): Update the documentation of #'sort here, now that it accepts any type of sequence and the KEY keyword argument. (Though this is probably now the wrong place for this function, given that.)
author Aidan Kehoe <kehoea@parhasard.net>
date Thu, 01 Apr 2010 20:22:50 +0100
parents 88bd4f3ef8e4
children f283b08ff0c9
comparison
equal deleted inserted replaced
5181:a00bfbd64e0a 5182:2e528066e2fc
735 if (!NILP (Fkeymapp (value))) 735 if (!NILP (Fkeymapp (value)))
736 *result_locative = Fcons (Fcons (key, value), *result_locative); 736 *result_locative = Fcons (Fcons (key, value), *result_locative);
737 return 0; 737 return 0;
738 } 738 }
739 739
740 static int map_keymap_sort_predicate (Lisp_Object obj1, Lisp_Object obj2, 740 static Lisp_Object map_keymap_sort_predicate (Lisp_Object obj1,
741 Lisp_Object pred); 741 Lisp_Object obj2,
742 Lisp_Object pred,
743 Lisp_Object key_func);
742 744
743 static Lisp_Object 745 static Lisp_Object
744 keymap_submaps (Lisp_Object keymap) 746 keymap_submaps (Lisp_Object keymap)
745 { 747 {
746 /* This function can GC */ 748 /* This function can GC */
759 &keymap_submaps_closure); 761 &keymap_submaps_closure);
760 result = Qnil; 762 result = Qnil;
761 elisp_maphash (keymap_submaps_mapper, k->table, 763 elisp_maphash (keymap_submaps_mapper, k->table,
762 &keymap_submaps_closure); 764 &keymap_submaps_closure);
763 /* keep it sorted so that the result of accessible-keymaps is ordered */ 765 /* keep it sorted so that the result of accessible-keymaps is ordered */
764 k->sub_maps_cache = list_sort (result, 766 k->sub_maps_cache = list_sort (result, map_keymap_sort_predicate,
765 Qnil, 767 Qnil, Qidentity);
766 map_keymap_sort_predicate);
767 UNGCPRO; 768 UNGCPRO;
768 } 769 }
769 return k->sub_maps_cache; 770 return k->sub_maps_cache;
770 } 771 }
771 772
2887 2888
2888 2889
2889 /* used by map_keymap_sorted(), describe_map_sort_predicate(), 2890 /* used by map_keymap_sorted(), describe_map_sort_predicate(),
2890 and keymap_submaps(). 2891 and keymap_submaps().
2891 */ 2892 */
2892 static int 2893 static Lisp_Object
2893 map_keymap_sort_predicate (Lisp_Object obj1, Lisp_Object obj2, 2894 map_keymap_sort_predicate (Lisp_Object obj1, Lisp_Object obj2,
2894 Lisp_Object UNUSED (pred)) 2895 Lisp_Object UNUSED (pred),
2896 Lisp_Object UNUSED (key_func))
2895 { 2897 {
2896 /* obj1 and obj2 are conses with keysyms in their cars. Cdrs are ignored. 2898 /* obj1 and obj2 are conses with keysyms in their cars. Cdrs are ignored.
2897 */ 2899 */
2898 int bit1, bit2; 2900 int bit1, bit2;
2899 int sym1_p = 0; 2901 int sym1_p = 0;
2902 2904
2903 obj1 = XCAR (obj1); 2905 obj1 = XCAR (obj1);
2904 obj2 = XCAR (obj2); 2906 obj2 = XCAR (obj2);
2905 2907
2906 if (EQ (obj1, obj2)) 2908 if (EQ (obj1, obj2))
2907 return -1; 2909 return Qnil;
2908 bit1 = MODIFIER_HASH_KEY_BITS (obj1); 2910 bit1 = MODIFIER_HASH_KEY_BITS (obj1);
2909 bit2 = MODIFIER_HASH_KEY_BITS (obj2); 2911 bit2 = MODIFIER_HASH_KEY_BITS (obj2);
2910 2912
2911 /* If either is a symbol with a Qcharacter_of_keysym property, then sort it by 2913 /* If either is a symbol with a Qcharacter_of_keysym property, then sort it by
2912 that code instead of alphabetically. 2914 that code instead of alphabetically.
2932 } 2934 }
2933 } 2935 }
2934 2936
2935 /* all symbols (non-ASCIIs) come after characters (ASCIIs) */ 2937 /* all symbols (non-ASCIIs) come after characters (ASCIIs) */
2936 if (XTYPE (obj1) != XTYPE (obj2)) 2938 if (XTYPE (obj1) != XTYPE (obj2))
2937 return SYMBOLP (obj2) ? 1 : -1; 2939 return SYMBOLP (obj2) ? Qt : Qnil;
2938 2940
2939 if (! bit1 && CHARP (obj1)) /* they're both ASCII */ 2941 if (! bit1 && CHARP (obj1)) /* they're both ASCII */
2940 { 2942 {
2941 int o1 = XCHAR (obj1); 2943 int o1 = XCHAR (obj1);
2942 int o2 = XCHAR (obj2); 2944 int o2 = XCHAR (obj2);
2943 if (o1 == o2 && /* If one started out as a symbol and the */ 2945 if (o1 == o2 && /* If one started out as a symbol and the */
2944 sym1_p != sym2_p) /* other didn't, the symbol comes last. */ 2946 sym1_p != sym2_p) /* other didn't, the symbol comes last. */
2945 return sym2_p ? 1 : -1; 2947 return sym2_p ? Qt : Qnil;
2946 2948
2947 return o1 < o2 ? 1 : -1; /* else just compare them */ 2949 return o1 < o2 ? Qt : Qnil; /* else just compare them */
2948 } 2950 }
2949 2951
2950 /* else they're both symbols. If they're both buckys, then order them. */ 2952 /* else they're both symbols. If they're both buckys, then order them. */
2951 if (bit1 && bit2) 2953 if (bit1 && bit2)
2952 return bit1 < bit2 ? 1 : -1; 2954 return bit1 < bit2 ? Qt : Qnil;
2953 2955
2954 /* if only one is a bucky, then it comes later */ 2956 /* if only one is a bucky, then it comes later */
2955 if (bit1 || bit2) 2957 if (bit1 || bit2)
2956 return bit2 ? 1 : -1; 2958 return bit2 ? Qt : Qnil;
2957 2959
2958 /* otherwise, string-sort them. */ 2960 /* otherwise, string-sort them. */
2959 { 2961 {
2960 Ibyte *s1 = XSTRING_DATA (XSYMBOL (obj1)->name); 2962 Ibyte *s1 = XSTRING_DATA (XSYMBOL (obj1)->name);
2961 Ibyte *s2 = XSTRING_DATA (XSYMBOL (obj2)->name); 2963 Ibyte *s2 = XSTRING_DATA (XSYMBOL (obj2)->name);
2962 return 0 > qxestrcmp (s1, s2) ? 1 : -1; 2964 return 0 > qxestrcmp (s1, s2) ? Qt : Qnil;
2963 } 2965 }
2964 } 2966 }
2965 2967
2966 2968
2967 /* used by map_keymap() */ 2969 /* used by map_keymap() */
2985 { 2987 {
2986 struct map_keymap_sorted_closure c1; 2988 struct map_keymap_sorted_closure c1;
2987 c1.result_locative = &contents; 2989 c1.result_locative = &contents;
2988 elisp_maphash (map_keymap_sorted_mapper, keymap_table, &c1); 2990 elisp_maphash (map_keymap_sorted_mapper, keymap_table, &c1);
2989 } 2991 }
2990 contents = list_sort (contents, Qnil, map_keymap_sort_predicate); 2992 contents = list_sort (contents, map_keymap_sort_predicate, Qnil, Qidentity);
2991 for (; !NILP (contents); contents = XCDR (contents)) 2993 for (; !NILP (contents); contents = XCDR (contents))
2992 { 2994 {
2993 Lisp_Object keysym = XCAR (XCAR (contents)); 2995 Lisp_Object keysym = XCAR (XCAR (contents));
2994 Lisp_Object binding = XCDR (XCAR (contents)); 2996 Lisp_Object binding = XCDR (XCAR (contents));
2995 int sub_bits = MODIFIER_HASH_KEY_BITS (keysym); 2997 int sub_bits = MODIFIER_HASH_KEY_BITS (keysym);
4078 binding), 4080 binding),
4079 *(closure->list)); 4081 *(closure->list));
4080 } 4082 }
4081 4083
4082 4084
4083 static int 4085 static Lisp_Object
4084 describe_map_sort_predicate (Lisp_Object obj1, Lisp_Object obj2, 4086 describe_map_sort_predicate (Lisp_Object obj1, Lisp_Object obj2,
4085 Lisp_Object pred) 4087 Lisp_Object pred, Lisp_Object key_func)
4086 { 4088 {
4087 /* obj1 and obj2 are conses of the form 4089 /* obj1 and obj2 are conses of the form
4088 ( ( <keysym> . <modifiers> ) . <binding> ) 4090 ( ( <keysym> . <modifiers> ) . <binding> )
4089 keysym and modifiers are used, binding is ignored. 4091 keysym and modifiers are used, binding is ignored.
4090 */ 4092 */
4092 obj1 = XCAR (obj1); 4094 obj1 = XCAR (obj1);
4093 obj2 = XCAR (obj2); 4095 obj2 = XCAR (obj2);
4094 bit1 = XINT (XCDR (obj1)); 4096 bit1 = XINT (XCDR (obj1));
4095 bit2 = XINT (XCDR (obj2)); 4097 bit2 = XINT (XCDR (obj2));
4096 if (bit1 != bit2) 4098 if (bit1 != bit2)
4097 return bit1 < bit2 ? 1 : -1; 4099 return bit1 < bit2 ? Qt : Qnil;
4098 else 4100 else
4099 return map_keymap_sort_predicate (obj1, obj2, pred); 4101 return map_keymap_sort_predicate (obj1, obj2, pred, key_func);
4100 } 4102 }
4101 4103
4102 /* Elide 2 or more consecutive numeric keysyms bound to the same thing, 4104 /* Elide 2 or more consecutive numeric keysyms bound to the same thing,
4103 or 2 or more symbolic keysyms that are bound to the same thing and 4105 or 2 or more symbolic keysyms that are bound to the same thing and
4104 have consecutive character-set-properties. 4106 have consecutive character-set-properties.
4202 traverse_keymaps (keymap, Qnil, 4204 traverse_keymaps (keymap, Qnil,
4203 describe_map_parent_mapper, &describe_map_closure); 4205 describe_map_parent_mapper, &describe_map_closure);
4204 4206
4205 if (!NILP (list)) 4207 if (!NILP (list))
4206 { 4208 {
4207 list = list_sort (list, Qnil, describe_map_sort_predicate); 4209 list = list_sort (list, describe_map_sort_predicate, Qnil, Qidentity);
4208 buffer_insert_ascstring (buf, "\n"); 4210 buffer_insert_ascstring (buf, "\n");
4209 while (!NILP (list)) 4211 while (!NILP (list))
4210 { 4212 {
4211 Lisp_Object elt = XCAR (XCAR (list)); 4213 Lisp_Object elt = XCAR (XCAR (list));
4212 Lisp_Object keysym = XCAR (elt); 4214 Lisp_Object keysym = XCAR (elt);