Mercurial > hg > xemacs-beta
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); |