annotate lisp/specifier.el @ 4981:4aebb0131297

Cleanups/renaming of EXTERNAL_TO_C_STRING and friends -------------------- ChangeLog entries follow: -------------------- modules/ChangeLog addition: 2010-02-05 Ben Wing <ben@xemacs.org> * postgresql/postgresql.c: * postgresql/postgresql.c (CHECK_LIVE_CONNECTION): * postgresql/postgresql.c (Fpq_connectdb): * postgresql/postgresql.c (Fpq_connect_start): * postgresql/postgresql.c (Fpq_lo_import): * postgresql/postgresql.c (Fpq_lo_export): * ldap/eldap.c (Fldap_open): * ldap/eldap.c (Fldap_search_basic): * ldap/eldap.c (Fldap_add): * ldap/eldap.c (Fldap_modify): * ldap/eldap.c (Fldap_delete): * canna/canna_api.c (Fcanna_initialize): * canna/canna_api.c (Fcanna_store_yomi): * canna/canna_api.c (Fcanna_parse): * canna/canna_api.c (Fcanna_henkan_begin): EXTERNAL_TO_C_STRING returns its argument instead of storing it in a parameter, and is renamed to EXTERNAL_TO_ITEXT. Similar things happen to related macros. See entry in src/ChangeLog. More Mule-izing of postgresql.c. Extract out common code between `pq-connectdb' and `pq-connect-start'. Fix places that signal an error string using a formatted string to instead follow the standard and have a fixed reason followed by the particular error message stored as one of the frobs. src/ChangeLog addition: 2010-02-05 Ben Wing <ben@xemacs.org> * console-msw.c (write_string_to_mswindows_debugging_output): * console-msw.c (Fmswindows_message_box): * console-x.c (x_perhaps_init_unseen_key_defaults): * console.c: * database.c (dbm_get): * database.c (dbm_put): * database.c (dbm_remove): * database.c (berkdb_get): * database.c (berkdb_put): * database.c (berkdb_remove): * database.c (Fopen_database): * device-gtk.c (gtk_init_device): * device-msw.c (msprinter_init_device_internal): * device-msw.c (msprinter_default_printer): * device-msw.c (msprinter_init_device): * device-msw.c (sync_printer_with_devmode): * device-msw.c (Fmsprinter_select_settings): * device-x.c (sanity_check_geometry_resource): * device-x.c (Dynarr_add_validified_lisp_string): * device-x.c (x_init_device): * device-x.c (Fx_put_resource): * device-x.c (Fx_valid_keysym_name_p): * device-x.c (Fx_set_font_path): * dialog-msw.c (push_lisp_string_as_unicode): * dialog-msw.c (handle_directory_dialog_box): * dialog-msw.c (handle_file_dialog_box): * dialog-x.c (dbox_descriptor_to_widget_value): * editfns.c (Fformat_time_string): * editfns.c (Fencode_time): * editfns.c (Fset_time_zone_rule): * emacs.c (make_argc_argv): * emacs.c (Fdump_emacs): * emodules.c (emodules_load): * eval.c: * eval.c (maybe_signal_error_1): * event-msw.c (Fdde_alloc_advise_item): * event-msw.c (mswindows_dde_callback): * event-msw.c (mswindows_wnd_proc): * fileio.c (report_error_with_errno): * fileio.c (Fsysnetunam): * fileio.c (Fdo_auto_save): * font-mgr.c (extract_fcapi_string): * font-mgr.c (Ffc_config_app_font_add_file): * font-mgr.c (Ffc_config_app_font_add_dir): * font-mgr.c (Ffc_config_filename): * frame-gtk.c (gtk_set_frame_text_value): * frame-gtk.c (gtk_create_widgets): * frame-msw.c (mswindows_init_frame_1): * frame-msw.c (mswindows_set_title_from_ibyte): * frame-msw.c (msprinter_init_frame_3): * frame-x.c (x_set_frame_text_value): * frame-x.c (x_set_frame_properties): * frame-x.c (start_drag_internal_1): * frame-x.c (x_cde_transfer_callback): * frame-x.c (x_create_widgets): * glyphs-eimage.c (my_jpeg_output_message): * glyphs-eimage.c (jpeg_instantiate): * glyphs-eimage.c (gif_instantiate): * glyphs-eimage.c (png_instantiate): * glyphs-eimage.c (tiff_instantiate): * glyphs-gtk.c (xbm_instantiate_1): * glyphs-gtk.c (gtk_xbm_instantiate): * glyphs-gtk.c (gtk_xpm_instantiate): * glyphs-gtk.c (gtk_xface_instantiate): * glyphs-gtk.c (cursor_font_instantiate): * glyphs-gtk.c (gtk_redisplay_widget): * glyphs-gtk.c (gtk_widget_instantiate_1): * glyphs-gtk.c (gtk_add_tab_item): * glyphs-msw.c (mswindows_xpm_instantiate): * glyphs-msw.c (bmp_instantiate): * glyphs-msw.c (mswindows_resource_instantiate): * glyphs-msw.c (xbm_instantiate_1): * glyphs-msw.c (mswindows_xbm_instantiate): * glyphs-msw.c (mswindows_xface_instantiate): * glyphs-msw.c (mswindows_redisplay_widget): * glyphs-msw.c (mswindows_widget_instantiate): * glyphs-msw.c (add_tree_item): * glyphs-msw.c (add_tab_item): * glyphs-msw.c (mswindows_combo_box_instantiate): * glyphs-msw.c (mswindows_widget_query_string_geometry): * glyphs-x.c (x_locate_pixmap_file): * glyphs-x.c (xbm_instantiate_1): * glyphs-x.c (x_xbm_instantiate): * glyphs-x.c (extract_xpm_color_names): * glyphs-x.c (x_xpm_instantiate): * glyphs-x.c (x_xface_instantiate): * glyphs-x.c (autodetect_instantiate): * glyphs-x.c (safe_XLoadFont): * glyphs-x.c (cursor_font_instantiate): * glyphs-x.c (x_redisplay_widget): * glyphs-x.c (Fchange_subwindow_property): * glyphs-x.c (x_widget_instantiate): * glyphs-x.c (x_tab_control_redisplay): * glyphs.c (pixmap_to_lisp_data): * gui-x.c (menu_separator_style_and_to_external): * gui-x.c (add_accel_and_to_external): * gui-x.c (button_item_to_widget_value): * hpplay.c (player_error_internal): * hpplay.c (play_sound_file): * hpplay.c (play_sound_data): * intl.c (Fset_current_locale): * lisp.h: * menubar-gtk.c (gtk_xemacs_set_accel_keys): * menubar-msw.c (populate_menu_add_item): * menubar-msw.c (populate_or_checksum_helper): * menubar-x.c (menu_item_descriptor_to_widget_value_1): * nt.c (init_user_info): * nt.c (get_long_basename): * nt.c (nt_get_resource): * nt.c (init_mswindows_environment): * nt.c (get_cached_volume_information): * nt.c (mswindows_readdir): * nt.c (read_unc_volume): * nt.c (mswindows_stat): * nt.c (mswindows_getdcwd): * nt.c (mswindows_executable_type): * nt.c (Fmswindows_short_file_name): * ntplay.c (nt_play_sound_file): * objects-gtk.c: * objects-gtk.c (gtk_valid_color_name_p): * objects-gtk.c (gtk_initialize_font_instance): * objects-gtk.c (gtk_font_list): * objects-msw.c (font_enum_callback_2): * objects-msw.c (parse_font_spec): * objects-x.c (x_parse_nearest_color): * objects-x.c (x_valid_color_name_p): * objects-x.c (x_initialize_font_instance): * objects-x.c (x_font_instance_truename): * objects-x.c (x_font_list): * objects-xlike-inc.c (XFUN): * objects-xlike-inc.c (xft_find_charset_font): * process-nt.c (mswindows_report_winsock_error): * process-nt.c (nt_create_process): * process-nt.c (get_internet_address): * process-nt.c (nt_open_network_stream): * process-unix.c: * process-unix.c (allocate_pty): * process-unix.c (get_internet_address): * process-unix.c (unix_canonicalize_host_name): * process-unix.c (unix_open_network_stream): * realpath.c: * select-common.h (lisp_data_to_selection_data): * select-gtk.c (symbol_to_gtk_atom): * select-gtk.c (atom_to_symbol): * select-msw.c (symbol_to_ms_cf): * select-msw.c (mswindows_register_selection_data_type): * select-x.c (symbol_to_x_atom): * select-x.c (x_atom_to_symbol): * select-x.c (hack_motif_clipboard_selection): * select-x.c (Fx_store_cutbuffer_internal): * sound.c (Fplay_sound_file): * sound.c (Fplay_sound): * sound.h (sound_perror): * sysdep.c: * sysdep.c (qxe_allocating_getcwd): * sysdep.c (qxe_execve): * sysdep.c (copy_in_passwd): * sysdep.c (qxe_getpwnam): * sysdep.c (qxe_ctime): * sysdll.c (dll_open): * sysdll.c (dll_function): * sysdll.c (dll_variable): * sysdll.c (search_linked_libs): * sysdll.c (dll_error): * sysfile.h: * sysfile.h (PATHNAME_CONVERT_OUT_TSTR): * sysfile.h (PATHNAME_CONVERT_OUT_UTF_8): * sysfile.h (PATHNAME_CONVERT_OUT): * sysfile.h (LISP_PATHNAME_CONVERT_OUT): * syswindows.h (ITEXT_TO_TSTR): * syswindows.h (LOCAL_FILE_FORMAT_TO_TSTR): * syswindows.h (TSTR_TO_LOCAL_FILE_FORMAT): * syswindows.h (LOCAL_FILE_FORMAT_TO_INTERNAL_MSWIN): * syswindows.h (LISP_LOCAL_FILE_FORMAT_MAYBE_URL_TO_TSTR): * text.h: * text.h (eicpy_ext_len): * text.h (enum new_dfc_src_type): * text.h (EXTERNAL_TO_ITEXT): * text.h (GET_STRERROR): * tooltalk.c (check_status): * tooltalk.c (Fadd_tooltalk_message_arg): * tooltalk.c (Fadd_tooltalk_pattern_attribute): * tooltalk.c (Fadd_tooltalk_pattern_arg): * win32.c (tstr_to_local_file_format): * win32.c (mswindows_lisp_error_1): * win32.c (mswindows_report_process_error): * win32.c (Fmswindows_shell_execute): * win32.c (mswindows_read_link_1): Changes involving external/internal format conversion, mostly code cleanup and renaming. 1. Eliminate the previous macros like LISP_STRING_TO_EXTERNAL that stored its result in a parameter. The new version of LISP_STRING_TO_EXTERNAL returns its result through the return value, same as the previous NEW_LISP_STRING_TO_EXTERNAL. Use the new-style macros throughout the code. 2. Rename C_STRING_TO_EXTERNAL and friends to ITEXT_TO_EXTERNAL, in keeping with overall naming rationalization involving Itext and related types. Macros involved in previous two: EXTERNAL_TO_C_STRING -> EXTERNAL_TO_ITEXT EXTERNAL_TO_C_STRING_MALLOC -> EXTERNAL_TO_ITEXT_MALLOC SIZED_EXTERNAL_TO_C_STRING -> SIZED_EXTERNAL_TO_ITEXT SIZED_EXTERNAL_TO_C_STRING_MALLOC -> SIZED_EXTERNAL_TO_ITEXT_MALLOC C_STRING_TO_EXTERNAL -> ITEXT_TO_EXTERNAL C_STRING_TO_EXTERNAL_MALLOC -> ITEXT_TO_EXTERNAL_MALLOC LISP_STRING_TO_EXTERNAL LISP_STRING_TO_EXTERNAL_MALLOC LISP_STRING_TO_TSTR C_STRING_TO_TSTR -> ITEXT_TO_TSTR TSTR_TO_C_STRING -> TSTR_TO_ITEXT The following four still return their values through parameters, since they have more than one value to return: C_STRING_TO_SIZED_EXTERNAL -> ITEXT_TO_SIZED_EXTERNAL LISP_STRING_TO_SIZED_EXTERNAL C_STRING_TO_SIZED_EXTERNAL_MALLOC -> ITEXT_TO_SIZED_EXTERNAL_MALLOC LISP_STRING_TO_SIZED_EXTERNAL_MALLOC Sometimes additional casts had to be inserted, since the old macros played strange games and completely defeated the type system of the store params. 3. Rewrite many places where direct calls to TO_EXTERNAL_FORMAT occurred with calls to one of the convenience macros listed above, or to make_extstring(). 4. Eliminate SIZED_C_STRING macros (they were hardly used, anyway) and use a direct call to TO_EXTERNAL_FORMAT or TO_INTERNAL_FORMAT. 4. Use LISP_PATHNAME_CONVERT_OUT in many places instead of something like LISP_STRING_TO_EXTERNAL(..., Qfile_name). 5. Eliminate some temporary variables that are no longer necessary now that we return a value rather than storing it into a variable. 6. Some Mule-izing in database.c. 7. Error functions: -- A bit of code cleanup in maybe_signal_error_1. -- Eliminate report_file_type_error; it's just an alias for signal_error_2 with params in a different order. -- Fix some places in the hostname-handling code that directly inserted externally-retrieved error strings into the supposed ASCII "reason" param instead of doing the right thing and sticking text descriptive of what was going on in "reason" and putting the external message in a frob. 8. Use Ascbyte instead of CIbyte in process-unix.c and maybe one or two other places. 9. Some code cleanup in copy_in_passwd() in sysdep.c. 10. Fix a real bug due to accidental variable shadowing in tstr_to_local_file_format() in win32.c.
author Ben Wing <ben@xemacs.org>
date Fri, 05 Feb 2010 11:02:24 -0600
parents b75b075a9041
children 18c0b5909d16
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 ;;; specifier.el --- Lisp interface to specifiers
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 ;; Copyright (C) 1997 Free Software Foundation, Inc.
3061
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
4 ;; Copyright (C) 1995, 1996, 2000, 2002, 2005 Ben Wing.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6 ;; Author: Ben Wing <ben@xemacs.org>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7 ;; Keywords: internal, dumped
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 ;;; Synched up with: Not in FSF.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 ;; This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 ;; XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 ;; under the terms of the GNU General Public License as published by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 ;; the Free Software Foundation; either version 2, or (at your option)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 ;; any later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 ;; XEmacs is distributed in the hope that it will be useful, but
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 ;; General Public License for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 ;; You should have received a copy of the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 ;; along with XEmacs; see the file COPYING. If not, write to the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 ;; Free Software Foundation, 59 Temple Place - Suite 330,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 ;; Boston, MA 02111-1307, USA.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 ;;; Commentary:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 ;; This file is dumped with XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 ;;; Code:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 (defun make-specifier-and-init (type spec-list &optional dont-canonicalize)
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
35 "Create and initialize a specifier of type TYPE with spec(s) SPEC-LIST.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
37 A convenience API combining `make-specifier' and `set-specifier', allowing you
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
38 to create a specifier and add specs to it at the same time.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
39 TYPE specifies the specifier type. See `make-specifier' for known types.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
40 SPEC-LIST supplies the specification(s) to be added to the specifier, in any
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
41 form acceptable to `canonicalize-spec-list'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
42 Optional DONT-CANONICALIZE, if non-nil, inhibits the conversion, and the
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
43 SPEC-LIST must already be in full form."
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 (let ((sp (make-specifier type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 (if (not dont-canonicalize)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 (setq spec-list (canonicalize-spec-list spec-list type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 (add-spec-list-to-specifier sp spec-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 sp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 ;; God damn, do I hate dynamic scoping.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
52 (defun map-specifier (ms-specifier ms-func &optional ms-locale ms-maparg
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
53 ms-tag-set ms-exact-p)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 "Apply MS-FUNC to the specification(s) for MS-LOCALE in MS-SPECIFIER.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
56 If optional MS-LOCALE is a locale, MS-FUNC will be called for that locale.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
57 If MS-LOCALE is a locale type, MS-FUNC will be mapped over all locales of that
3061
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
58 type. If MS-LOCALE is `all' or nil, MS-FUNC will be mapped over all locales in
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
59 MS-SPECIFIER.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
61 Optional MS-TAG-SET and MS-EXACT-P are as in `specifier-spec-list'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
62 Optional MS-MAPARG will be passed to MS-FUNC.
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
63
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 MS-FUNC is called with four arguments: the MS-SPECIFIER, the locale
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 being mapped over, the inst-list for that locale, and the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 optional MS-MAPARG. If any invocation of MS-FUNC returns non-nil,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 the mapping will stop and the returned value becomes the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 value returned from `map-specifier'. Otherwise, `map-specifier'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 returns nil."
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
70 (let ((ms-specs (specifier-spec-list ms-specifier ms-locale ms-tag-set
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
71 ms-exact-p))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 ms-result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 (while (and ms-specs (not ms-result))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 (let ((ms-this-spec (car ms-specs)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 (setq ms-result (funcall ms-func ms-specifier (car ms-this-spec)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 (cdr ms-this-spec) ms-maparg))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 (setq ms-specs (cdr ms-specs))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 ms-result))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 (defun canonicalize-inst-pair (inst-pair specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 "Canonicalize the given INST-PAIR.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 SPECIFIER-TYPE specifies the type of specifier that this SPEC-LIST
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 will be used for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 Canonicalizing means converting to the full form for an inst-pair, i.e.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 `(TAG-SET . INSTANTIATOR)'. A single, untagged instantiator is given
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 a tag set of nil (the empty set), and a single tag is converted into
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 a tag set consisting only of that tag.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 If NOERROR is non-nil, signal an error if the inst-pair is invalid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 ;; a) a single instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 ;; b) a cons of a tag and an instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 ;; c) a cons of a tag set and an instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 (cond ((valid-instantiator-p inst-pair specifier-type)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 (cons nil inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 ((not (consp inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 ;; not an inst-pair
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 (check-valid-instantiator inst-pair specifier-type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 ((and (valid-specifier-tag-p (car inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 (valid-instantiator-p (cdr inst-pair) specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 (cons (list (car inst-pair)) (cdr inst-pair)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 ((and (valid-specifier-tag-set-p (car inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 (valid-instantiator-p (cdr inst-pair) specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 ;; case (c)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 inst-pair)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 (signal 'error (list "Invalid specifier tag set"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 (car inst-pair)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 (defun canonicalize-inst-list (inst-list specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 "Canonicalize the given INST-LIST (a list of inst-pairs).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 SPECIFIER-TYPE specifies the type of specifier that this INST-LIST
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 will be used for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 Canonicalizing means converting to the full form for an inst-list, i.e.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 `((TAG-SET . INSTANTIATOR) ...)'. This function accepts a single
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 inst-pair or any abbreviation thereof or a list of (possibly
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 abbreviated) inst-pairs. (See `canonicalize-inst-pair'.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 If NOERROR is non-nil, signal an error if the inst-list is invalid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 ;; a) an inst-pair or various abbreviations thereof
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 ;; b) a list of (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 (let ((result (canonicalize-inst-pair inst-list specifier-type t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 (if (not (eq result t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 (list result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 (if (not (consp inst-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 ;; not an inst-list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 (check-valid-instantiator inst-list specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 (catch 'cann-inst-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 ;; don't use mapcar here; we need to catch the case of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 ;; an invalid list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 (let ((rest inst-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 (result nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 (if (not (consp rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 (if noerror (throw 'cann-inst-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 (signal 'error (list "Invalid list format" inst-list)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 (let ((res2 (canonicalize-inst-pair (car rest) specifier-type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 noerror)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 (if (eq res2 t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 ;; at this point, we know we're noerror because
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 ;; otherwise canonicalize-inst-pair would have
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 ;; signalled an error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 (throw 'cann-inst-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 (setq result (cons res2 result)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 (setq rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 (nreverse result)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 (defun canonicalize-spec (spec specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 "Canonicalize the given SPEC (a specification).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
176 SPECIFIER-TYPE is the type of specifier that this SPEC will be used for.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 Canonicalizing means converting to the full form for a spec, i.e.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 `(LOCALE (TAG-SET . INSTANTIATOR) ...)'. This function accepts a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 possibly abbreviated inst-list or a cons of a locale and a possibly
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 abbreviated inst-list. (See `canonicalize-inst-list'.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 If NOERROR is nil, signal an error if the specification is invalid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 ;; a) an inst-list or some abbreviation thereof
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 ;; b) a cons of a locale and an inst-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 (let ((result (canonicalize-inst-list spec specifier-type t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 (if (not (eq result t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 (cons 'global result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 (if (not (consp spec))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 ;; not a spec.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 (check-valid-instantiator spec specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200 (if (not (valid-specifier-locale-p (car spec)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 ;; invalid locale.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 (signal 'error (list "Invalid specifier locale" (car spec))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 (let ((result (canonicalize-inst-list (cdr spec) specifier-type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 noerror)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 (if (eq result t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 ;; at this point, we know we're noerror because
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 ;; otherwise canonicalize-inst-list would have
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 ;; signalled an error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 (cons (car spec) result))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 (defun canonicalize-spec-list (spec-list specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 "Canonicalize the given SPEC-LIST (a list of specifications).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218 SPECIFIER-TYPE specifies the type of specifier that this SPEC-LIST
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 will be used for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 Canonicalizing means converting to the full form for a spec-list, i.e.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 `((LOCALE (TAG-SET . INSTANTIATOR) ...) ...)'. This function accepts
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 a possibly abbreviated specification or a list of such things. (See
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 `canonicalize-spec'.) This is the function used to convert spec-lists
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 accepted by `set-specifier' and such into a form suitable for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 `add-spec-list-to-specifier'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
228 The canonicalization algorithm is as follows:
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
229
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
230 1. Attempt to parse SPEC-LIST as a single, possibly abbreviated, specification.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
231 2. If (1) fails, attempt to parse SPEC-LIST as a list of (abbreviated)
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
232 specifications.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
233 3. If (2) fails, SPEC-LIST is invalid.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
234
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
235 A possibly abbreviated specification SPEC is parsed by
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
236
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
237 1. Attempt to parse SPEC as a possibly abbreviated inst-list.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
238 2. If (1) fails, attempt to parse SPEC as a cons of a locale and an
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
239 (abbreviated) inst-list.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
240 3. If (2) fails, SPEC is invalid.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
241
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
242 A possibly abbreviated inst-list INST-LIST is parsed by
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
243
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
244 1. Attempt to parse INST-LIST as a possibly abbreviated inst-pair.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
245 2. If (1) fails, attempt to parse INST-LIST as a list of (abbreviated)
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
246 inst-pairs.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
247 3. If (2) fails, INST-LIST is invalid.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
248
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
249 A possibly abbreviated inst-pair INST-PAIR is parsed by
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
250
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
251 1. Check if INST-PAIR is `valid-instantiator-p'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
252 2. If not, check if INST-PAIR is a cons of something that is a tag, ie,
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
253 `valid-specifier-tag-p', and something that is `valid-instantiator-p'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
254 3. If not, check if INST-PAIR is a cons of a list of tags and something that
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
255 is `valid-instantiator-p'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
256
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
257 In summary, this function generally prefers more abbreviated forms.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
258
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
259 This function tries extremely hard to resolve any ambiguities, and the
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
260 built-in specifier types (font, image, toolbar, etc.) are designed so that
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
261 there won't be any ambiguities. (#### Unfortunately there are bugs in the
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
262 treatment of toolbar spec-lists and generic spec-lists; avoid depending on
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
263 canonicalization for these types.)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 If NOERROR is nil, signal an error if the spec-list is invalid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 ;; a) a spec or various abbreviations thereof
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 ;; b) a list of (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 (let ((result (canonicalize-spec spec-list specifier-type t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 (if (not (eq result t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 (list result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 (if (not (consp spec-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 ;; not a spec-list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 (check-valid-instantiator spec-list specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 (catch 'cann-spec-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 ;; don't use mapcar here; we need to catch the case of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 ;; an invalid list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 (let ((rest spec-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 (result nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 (if (not (consp rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 (if noerror (throw 'cann-spec-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 (signal 'error (list "Invalid list format" spec-list)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 (let ((res2 (canonicalize-spec (car rest) specifier-type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293 noerror)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 (if (eq res2 t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 ;; at this point, we know we're noerror because
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296 ;; otherwise canonicalize-spec would have
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 ;; signalled an error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 (throw 'cann-spec-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 (setq result (cons res2 result)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 (setq rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301 (nreverse result)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 (defun set-specifier (specifier value &optional locale tag-set how-to-add)
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
304 "Add the specification(s) given by VALUE to SPECIFIER in LOCALE.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
305
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
306 VALUE may be any of the values accepted by `canonicalize-spec-list', including
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
307
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
308 -- an instantiator (either a Lisp object which will be returned when the
3061
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
309 specifier is instantiated, or a Lisp object that can be instantiated to
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
310 produce an opaque value: eg, a font name (string) can be used for a font
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
311 specifier, but an instance will be a font object)
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
312 -- a list of instantiators
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
313 -- a cons of a locale and an instantiator, or of a locale and a list of
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
314 instantiators
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
315 -- a cons of a tag or tag-set and an instantiator (or list of instantiators)
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
316 -- a cons of a locale and the previous type of item
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
317 -- a list of one or more of any of the previous types of items
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
318 -- a canonical spec-list.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
320 See `canonicalize-spec-list' for details. If you need to know the details,
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
321 though, strongly consider using the unambiguous APIs `add-spec-to-specifier'
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
322 and `add-spec-list-to-specifier' instead.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
323
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
324 Finally, VALUE can itself be a specifier (of the same type as
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
325 SPECIFIER), if you want to copy specifications from one specifier
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
326 to another; this is equivalent to calling `copy-specifier', and
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
327 LOCALE, TAG-SET, and HOW-TO-ADD have the same semantics as with
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
328 that function.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
329
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
330 Note that a VALUE of `nil' is either illegal or will be treated as a value of
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
331 `nil'; it does not remove existing specifications. Use `remove-specifier' for
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
332 that. N.B. `remove-specifier' defaults to removing all specifications, not
3061
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
333 just the `global' one!
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
334
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
335 Warning: this function is inherently heuristic, and should not be relied on to
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
336 properly resolve ambiguities, when specifier instantiators can be lists
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
337 \(currently, for toolbar specifiers and generic specifiers). In those cases
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
338 use either `add-spec-to-specifier' or `add-spec-list-to-specifier'.
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
339
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 LOCALE indicates where this specification is active, and should be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 a buffer, a window, a frame, a device, or the symbol `global' to
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
342 indicate that it applies everywhere. LOCALE defaults to
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
343 `global' if omitted, and is overridden by locales provided by VALUE (in the
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
344 cases where value is a full specification or a spec-list).
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
346 Optional argument TAG-SET is a tag or a list of tags, to be associated
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
347 with the VALUE. Tags are symbols (usually naming device types, such
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
348 as `x' and `tty', or device classes, such as `color', `mono', and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
349 `grayscale'); specifying a TAG-SET restricts the scope of VALUE to
2297
13a418960a88 [xemacs-hg @ 2004-09-22 02:05:42 by stephent]
stephent
parents: 1875
diff changeset
350 devices that match all specified tags. (You can also create your
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 own tags using `define-specifier-tag', and use them to identify
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 specifications added by you, so you can remove them later.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 Optional argument HOW-TO-ADD should be either nil or one of the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 symbols `prepend', `append', `remove-tag-set-prepend',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356 `remove-tag-set-append', `remove-locale', `remove-locale-type',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 or `remove-all'. This specifies what to do with existing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 specifications in LOCALE (and possibly elsewhere in the specifier).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 Most of the time, you do not need to worry about this argument;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 the default behavior of `remove-tag-set-prepend' is usually fine.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 See `copy-specifier' and `add-spec-to-specifier' for a full
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 description of what each of these means.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 Note that `set-specifier' is exactly complementary to `specifier-specs'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365 except in the case where SPECIFIER has no specs at all in it but nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 is a valid instantiator (in that case, `specifier-specs' will return
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 nil (meaning no specs) and `set-specifier' will interpret the `nil'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 as meaning \"I'm adding a global instantiator and its value is `nil'\"),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 or in strange cases where there is an ambiguity between a spec-list
2297
13a418960a88 [xemacs-hg @ 2004-09-22 02:05:42 by stephent]
stephent
parents: 1875
diff changeset
370 and an inst-list, etc. (The built-in specifier types are designed
1875
ec2d1e636272 [xemacs-hg @ 2004-01-23 10:00:20 by stephent]
stephent
parents: 872
diff changeset
371 in such a way as to avoid any such ambiguities.)"
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 ;; backward compatibility: the old function had HOW-TO-ADD as the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 ;; third argument and no arguments after that.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 ;; #### this should disappear at some point.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 (if (and (null how-to-add)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 (memq locale '(prepend append remove-tag-set-prepend
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 remove-tag-set-append remove-locale
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 remove-locale-type remove-all)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 (setq how-to-add locale)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 (setq locale nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 ;; proper beginning of the function.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 (let ((is-valid (valid-instantiator-p value (specifier-type specifier)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 (nval value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 (cond ((and (not is-valid) (specifierp nval))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 (copy-specifier nval specifier locale tag-set nil how-to-add))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 (if tag-set
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 (if (not (listp tag-set))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 (setq tag-set (list tag-set)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 ;; You tend to get more accurate errors
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 ;; for a variety of cases if you call
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 ;; canonicalize-tag-set here.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397 (setq tag-set (canonicalize-tag-set tag-set))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398 (if (and (not is-valid) (consp nval))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 (setq nval
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 (mapcar #'(lambda (x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 (check-valid-instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 x (specifier-type specifier))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 (cons tag-set x))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 nval))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 (setq nval (cons tag-set nval)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406 (if locale
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 (setq nval (cons locale nval)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 (add-spec-list-to-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409 specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 (canonicalize-spec-list nval (specifier-type specifier))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 how-to-add))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413
3061
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
414 ;; #### Misnamed and wrong behavior. Should operate on INSTANTIATORS, not
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
415 ;; instances. Need to come up with clean and general functions for
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
416 ;; modifying a specifier. New `specifier-instantiator' may help.
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
417 ;; #### Also need `instantiator-to-instance', a convenient version of
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
418 ;; `specifier-instance-from-inst-list'.
fd1acd2f457a [xemacs-hg @ 2005-11-13 07:39:26 by ben]
ben
parents: 2297
diff changeset
419
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
420 (defun modify-specifier-instances (specifier func &optional args force default
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
421 locale tag-set)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
422 "Modify all specifications that match LOCALE and TAG-SET by FUNC.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
423
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
424 For each specification that exists for SPECIFIER, in locale LOCALE
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
425 that matches TAG-SET, call the function FUNC with the instance as its
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
426 first argument and with optional arguments ARGS. The result is then
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
427 used as the new value of the instantiator.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
428
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
429 If there is no specification in the domain LOCALE matching TAG-SET and
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
430 FORCE is non-nil, an explicit one is created from the matching
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
431 specifier instance if that exists or DEFAULT otherwise. If LOCALE is
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
432 not a domain (i.e. a buffer), DEFAULT is always used. FUNC is then
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
433 applied like above and the resulting specification is added."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
434
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
435 (let ((spec-list (specifier-spec-list specifier locale tag-set)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
436 (cond
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
437 (spec-list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
438 ;; Destructively edit the spec-list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
439 (mapc #'(lambda (spec)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
440 (mapc #'(lambda (inst-pair)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
441 (setcdr inst-pair
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
442 (apply func (cdr inst-pair) args)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
443 (cdr spec)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
444 spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
445 (add-spec-list-to-specifier specifier spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
446 (force
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
447 (set-specifier specifier
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
448 (apply func
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
449 (or (and (valid-specifier-domain-p locale)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
450 (specifier-instance specifier))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
451 default) args)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
452 locale tag-set)))))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
453
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454 (defmacro let-specifier (specifier-list &rest body)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 "Add specifier specs, evaluate forms in BODY and restore the specifiers.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 \(let-specifier SPECIFIER-LIST BODY...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 Each element of SPECIFIER-LIST should look like this:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459 \(SPECIFIER VALUE &optional LOCALE TAG-SET HOW-TO-ADD).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 SPECIFIER is the specifier to be temporarily modified. VALUE is the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 instantiator to be temporarily added to SPECIFIER in LOCALE. LOCALE,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 TAG-SET and HOW-TO-ADD have the same meaning as in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 `add-spec-to-specifier'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 The code resulting from macro expansion will add specifications to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 specifiers using `add-spec-to-specifier'. After BODY is finished, the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 temporary specifications are removed and old spec-lists are restored.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 LOCALE, TAG-SET and HOW-TO-ADD may be omitted, and default to nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 The value of the last form in BODY is returned.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 NOTE: If you want the specifier's instance to change in all
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 circumstances, use (selected-window) as the LOCALE. If LOCALE is nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 or omitted, it defaults to `global'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 Example:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 (let-specifier ((modeline-shadow-thickness 0 (selected-window)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 (sit-for 1))"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 (check-argument-type 'listp specifier-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 (flet ((gensym-frob (x name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 (if (or (atom x) (eq (car x) 'quote))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 (list x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 (list (gensym name) x))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 ;; VARLIST is a list of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 ;; ((SPECIFIERSYM SPECIFIER) (VALUE) (LOCALESYM LOCALE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 ;; (TAG-SET) (HOW-TO-ADD))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488 ;; If any of these is an atom, then a separate symbol is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 ;; unnecessary, the CAR will contain the atom and CDR will be nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 (let* ((varlist (mapcar #'(lambda (listel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 (or (and (consp listel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492 (<= (length listel) 5)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 (> (length listel) 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 (signal 'error
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495 (list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 "should be a list of 2-5 elements"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 listel)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 ;; VALUE, TAG-SET and HOW-TO-ADD are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 ;; referenced only once, so we needn't
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 ;; frob them with gensym.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 (list (gensym-frob (nth 0 listel) "specifier-")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 (list (nth 1 listel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 (gensym-frob (nth 2 listel) "locale-")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 (list (nth 3 listel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 (list (nth 4 listel))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 specifier-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 ;; OLDVALLIST is a list of (OLDVALSYM OLDVALFORM)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 (oldvallist (mapcar #'(lambda (varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 (list (gensym "old-")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 `(specifier-spec-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 ,(car (nth 0 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 ,(car (nth 2 varel)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 varlist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 ;; Bind the appropriate variables.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 `(let* (,@(mapcan #'(lambda (varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 (delq nil (mapcar
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 #'(lambda (varcons)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 (and (cdr varcons) varcons))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 varel)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 varlist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 ,@oldvallist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 (unwind-protect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 ,@(mapcar #'(lambda (varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 `(add-spec-to-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 ,(car (nth 0 varel)) ,(car (nth 1 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 ,(car (nth 2 varel)) ,(car (nth 3 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 ,(car (nth 4 varel))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 varlist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 ,@body)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 ;; Reverse the unwinding order, so that using the same
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 ;; specifier multiple times works.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 ,@(apply #'nconc (nreverse (mapcar*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 #'(lambda (oldval varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 `((remove-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 ,(car (nth 0 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 ,(car (nth 2 varel)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 (add-spec-list-to-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539 ,(car (nth 0 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
540 ,(car oldval))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 oldvallist varlist))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
543 (defun make-integer-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
544 "Return a new `integer' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
545 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
546 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
547 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
548 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
549
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
550 Valid instantiators for integer specifiers are integers."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
551 (make-specifier-and-init 'integer spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
552
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
553 (defun make-boolean-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
554 "Return a new `boolean' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
555 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
556 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
557 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
558 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
559
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
560 Valid instantiators for boolean specifiers are t and nil."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
561 (make-specifier-and-init 'boolean spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
562
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
563 (defun make-natnum-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
564 "Return a new `natnum' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
565 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
566 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
567 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
568 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
569
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
570 Valid instantiators for natnum specifiers are non-negative integers."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
571 (make-specifier-and-init 'natnum spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
572
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
573 (defun make-generic-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
574 "Return a new `generic' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
575 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
576 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
577 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
578 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
579
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
580 Valid instantiators for generic specifiers are all Lisp values.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
581 They are returned back unchanged when a specifier is instantiated."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
582 (make-specifier-and-init 'generic spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
583
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
584 (defun make-display-table-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
585 "Return a new `display-table' specifier object with the given spec list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
586 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
587 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
588 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
589 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
590
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
591 Valid instantiators for display-table specifiers are described in
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
592 detail in the doc string for `current-display-table'."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
593 (make-specifier-and-init 'display-table spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
594
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595 ;; Evaluate this for testing:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 ; (cl-prettyexpand '(let-specifier ((modeline-shadow-thickness 0 (selected-window) 'x) (fubar (value) baz)) (sit-for 1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 (define-specifier-tag 'win 'device-on-window-system-p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 ;; Add tags for device types that don't have support compiled
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601 ;; into the binary that we're about to dump. This will prevent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602 ;; code like
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
603 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 ;; (set-face-foreground 'default "black" nil '(x color))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 ;; from producing an error if no X support was compiled in.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607
4194
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
608 (loop
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
609 for tag in '(x tty mswindows msprinter gtk carbon)
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
610 do (unless (valid-specifier-tag-p tag)
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
611 (define-specifier-tag tag #'ignore)))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
612
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
613 ;; Add special tag for use by initialization code. Code that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
614 ;; sets up default specs should use this tag. Code that needs to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
615 ;; override default specs (e.g. the X resource initialization
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
616 ;; code) can safely clear specs with this tag without worrying
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617 ;; about clobbering user settings.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 (define-specifier-tag 'default)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620
4194
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
621 ;; The x-resource specifier tag is provide so the X resource initialization
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
622 ;; code can be overridden by custom without trouble.
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
623
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
624 (define-specifier-tag 'x-resource)
4f2243a0dc04 [xemacs-hg @ 2007-09-30 11:59:34 by aidan]
aidan
parents: 3926
diff changeset
625
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
626 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
627 ;;; "Heuristic" specifier functions ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
628 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
629
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
630 ;;; "Heuristic" is a euphemism for kludge. This stuff works well in
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
631 ;;; practice, though.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
632
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
633 ;;; You might view all the contortions we do here and in Face-frob-property
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
634 ;;; as indicative of design failures with specifiers, and perhaps you're
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
635 ;;; right. But in fact almost all code that attempts to interface to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
636 ;;; humans and produce "intuitive" results gets messy, particularly with a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
637 ;;; system as complicated as specifiers, whose complexity results from an
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
638 ;;; attempt to work well in many different circumstances. We could create
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
639 ;;; a much simpler system, but the tradeoff would be that you'd have to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
640 ;;; programmatically control all the stuff that gets handled automatically
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
641 ;;; by setting the right specifiers -- and then things wouldn't "just work"
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
642 ;;; if the user simultaneously creates a TTY and X device, or X devices on
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
643 ;;; different types of machines, or wants some buffers to display
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
644 ;;; differently from others, etc. without a lot of hook functions and other
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
645 ;;; glue machinery to set everything up. The result would be just as much
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
646 ;;; complexity, but worse, and much harder to control, since there wouldn't
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
647 ;;; be any standard framework for managing all these hook functions and the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
648 ;;; user would have to be able to write lots of Lisp code to get things
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
649 ;;; working.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
650
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
651 ;;; The problem is that we have no high-level code, e.g. custom, to make it
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
652 ;;; easy for the user to control specifiers nicely. The following
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
653 ;;; lower-level code, though, should make it easier to implement the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
654 ;;; high-level code.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
655
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
656 ;;; #### Something like Face-frob-property, but more general, should be
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
657 ;;; created for general specifier frobbing.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
658
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
659 ;;; #### Other possible extensions to specifiers would be
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
660 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
661 ;;; (a) the ability to create specifications for particular types of
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
662 ;;; buffers, e.g. all C-mode buffers one way, all text-mode buffers
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
663 ;;; another way, etc. Perhaps this should be implemented through hook
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
664 ;;; functions; but that wouldn't easily allow you to `make-face-bold'
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
665 ;;; and have it work on these other kinds of specifications. Probably
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
666 ;;; a better way is to extend the tag mechanism so that it can specify
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
667 ;;; things other than device types. One way would be to simply allow
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
668 ;;; tags to have arbitrary elisp attached to them -- a function that
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
669 ;;; takes a domain and returns whether the attached instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
670 ;;; applies. This should be doable given (a) that we now have code to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
671 ;;; allow elisp to be run inside a "sandbox", sufficiently protected
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
672 ;;; that it can even be called from redisplay, and (b) the large amount
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
673 ;;; of caching we already have, which would minimize the speed hit.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
674 ;;; However, this still runs into problems -- (a) it requires
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
675 ;;; programming to get anything at all done, and (b) you'll get
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
676 ;;; horrible namespace clashes very quickly. Another possibility to be
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
677 ;;; used in conjunction with this would be vector tags, with an
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
678 ;;; extendable mechanism to control their syntax. For example,
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
679 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
680 ;;; [tag :mode 'c] (buffer in c-mode)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
681 ;;; [tag :buffer-name "\\*Help: function"] (help-on-function buffers)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
682 ;;; [tag :buffer-coding-system 'japanese-euc] (buffer's coding system is
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
683 ;;; EUC-JP)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
684 ;;; [tag :buffer-file-name "^#.*#$"] (autosave files)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
685 ;;; [tag :language-environment "French"] (whenever the global language
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
686 ;;; environment is French)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
687 ;;; [tag :font-height-minimum '(default 12)] (if the height of the default
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
688 ;;; font is at least 12 pixels
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
689 ;;; in this domain)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
690 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
691 ;;; The general idea is that the properties allowable in a tag vector
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
692 ;;; are extendable, just by specifying the property name and a function
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
693 ;;; of two arguments, the property value and the domain, which should
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
694 ;;; return whether the tag applies. You could imagine very complex
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
695 ;;; behavior (e.g. combining two tags in a single tag set makes an
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
696 ;;; `and', and putting the two tags separately with separate (perhaps
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
697 ;;; identical) instantiators makes an `or'. You could effectively do a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
698 ;;; lot of what you might want to do with hooks, but in a much more
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
699 ;;; controllable fashion. Obviously, much of this complexity wouldn't
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
700 ;;; necessarily be directly set by the user -- they wouldn't probably
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
701 ;;; do more than simple tags based on mode, buffer or file name, etc.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
702 ;;; But a higher-level interface could easily have various possible
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
703 ;;; "behaviors" to choose from, implemented using this mechanism.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
704 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
705 ;;; #### WE NEED CUSTOM SUPPORT!
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
706 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
707 ;;; (b) Another possibility is "partial" inheritance. For example --
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
708 ;;; toolbars and menubars are complex specifications. Currently the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
709 ;;; only way to make a change is to copy the entire value and make the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
710 ;;; necessary modifications. What we would like instead is to be able
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
711 ;;; to construct a mini-menubar that says something like "add this menu
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
712 ;;; here" and combine with everything else. That would require a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
713 ;;; slightly different approach to instantiation. Currently it just
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
714 ;;; searches up the tree from specific to general, looking for a match;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
715 ;;; from this match, it generates the instance. Instead, it would
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
716 ;;; potentially have to record all the matches it found and pass a list
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
717 ;;; of them to the instantiation function. To implement this, we would
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
718 ;;; create another specifier method "instantiator_inherits_up", which
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
719 ;;; looks at the instantiator to determine if it calls for combining
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
720 ;;; itself with the value higher up. this tells the specifier code
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
721 ;;; whether to stop now or keep going. It would then pass a Dynarr of
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
722 ;;; the instantiators to the instantiate method, which might be a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
723 ;;; special version, e.g. "instantiate_multi".
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
724
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
725 (defun instance-to-instantiator (inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
726 "Convert an instance to an instantiator.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
727 If we have an instance object, we fetch the instantiator that generated the object. Otherwise, we just return the instance."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
728 (cond ((font-instance-p inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
729 (setq inst (font-instance-name inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
730 ((color-instance-p inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
731 (setq inst (color-instance-name inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
732 ((image-instance-p inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
733 (setq inst (image-instance-instantiator inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
734 (t inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
735
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
736 (defun device-type-matches-spec (devtype devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
737 ;; Return DEVTYPE (a devtype) if it matches DEVTYPE-SPEC, else nil.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
738 ;; DEVTYPE-SPEC can be nil (all types OK), a device type (only that type
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
739 ;; OK), or `window-system' -- window system device types OK.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
740 (cond ((not devtype-spec) devtype)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
741 ((eq devtype-spec 'window-system)
3926
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
742 (and (not (memq devtype '(msprinter tty stream))) devtype))
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
743 (t (and (eq devtype devtype-spec) devtype))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
744
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
745 (defun add-tag-to-inst-list (inst-list tag-set)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
746 "Add TAG-SET (tag or tag-set) to all tags in INST-LIST."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
747 ;; Ah, all is sweetness and light with `loop'
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
748 (if (null tag-set) inst-list
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
749 (loop for (t2 . x2) in inst-list
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
750 for newt2 = (delete-duplicates
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
751 (append (if (listp tag-set) tag-set (list tag-set))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
752 (if (listp t2) t2 (list t2))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
753 collect (cons newt2 x2))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
754
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
755 (defun derive-domain-from-locale (locale &optional devtype-spec current-device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
756 "Given a locale, try to derive the \"most reasonable\" domain.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
757
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
758 This is a heuristic \(\"works most of the time\") algorithm.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
759
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
760 \[Remember that, in specifiers, locales are what you attach specifications or
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
761 \"instantiators\" to, and domains are the contexts in which you can
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
762 retrieve the value or \"instance\" of the specifier. Not all locales are
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
763 domains. In particular, buffers are locales but not domains because
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
764 buffers may be displayed in different windows on different frames, and thus
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
765 end up with different values if the frames each have a frame-local
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
766 instantiator and the instantiators are different. However, we may well
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
767 find ourselves in a situation where we want to figure out the most likely
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
768 value of a specifier in a buffer -- for example we might conceptually want
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
769 to make a buffer's modeline face be bold, so we need to figure out what the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
770 current face is. If the buffer already has an instantiator, it's easy; but
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
771 if it doesn't, we want to do something reasonable rather than just issue an
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
772 error, even though technically the value is not well-defined. We want
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
773 something that gives the right answer most of the time.]
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
774
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
775 LOCALE is a specifier locale -- i.e. a buffer, window, frame, device, the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
776 symbol `global', or nil, meaning the same as `global'.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
777
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
778 DEVTYPE-SPEC, if given, can restrict the possible return values to domains
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
779 on devices of that device type; or if it's `window-system', to domains on
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
780 window-system devices.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
781
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
782 CURRENT-DEVICE is what should be considered as the \"selected device\" when
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
783 this value is needed. It defaults to the currently selected device.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
784
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
785 -- If LOCALE is a domain, it's simply returned.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
786 -- If LOCALE is `all', `global', or nil, we return CURRENT-DEVICE.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
787 -- If LOCALE is a buffer, we use `get-buffer-window' to find a window viewing
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
788 the buffer, and return it if there is one; otherwise we return the selected
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
789 window on CURRENT-DEVICE.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
790
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
791 The return value may be nil if the only possible values don't agree with
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
792 DEVTYPE-SPEC."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
793 ;; DEVICE aims to be the selected device, but picks some other
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
794 ;; device if that won't work. may be nil.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
795 (let* ((device (or current-device (selected-device)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
796 (device (if (device-type-matches-spec (device-type device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
797 devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
798 device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
799 (first
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
800 (delete-if-not
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
801 #'(lambda (x)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
802 (device-type-matches-spec (device-type x)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
803 devtype-spec))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
804 (device-list))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
805 (cond ((memq locale '(all nil global)) device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
806 ((valid-specifier-domain-p locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
807 (and (device-type-matches-spec (device-type (dfw-device locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
808 devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
809 locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
810 ((bufferp locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
811 (let ((win (get-buffer-window locale t devtype-spec)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
812 (or win (and device (selected-window device))))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
813
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
814 (defun derive-device-type-from-tag-set (tag-set &optional try-stages
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
815 devtype-spec current-device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
816 "Given a tag set, try (heuristically) to get a device type from it.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
817
3926
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
818 If CURRENT-DEVICE is supplied, then this function either returns its type,
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
819 in the event that it matches TAG-SET, or nil.
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
820
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
821 Otherwise, there are three stages that it proceeds through, each one trying
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
822 harder than the previous to get a value. TRY-STAGES controls how many
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
823 stages to try. If nil or 1, only stage 1 is done; if 2; stages 1 and 2 are
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
824 done; if 3, stages 1-3 are done; if t, all stages are done (currently 1-3).
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
825
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
826 Stage 1 looks at the tags themselves to see if any of them are device-type
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
827 tags. If so, it returns the device type. If there is more than one device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
828 type, this tag can never match anything, but we go ahead and return one of
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
829 them. If no device types in the tags, we fail.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
830
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
831 Stage 2 runs all devices through the tag set to see if any match, and
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
832 accumulate a list of device types of all matching devices. If there is
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
833 exactly one device type in the list, we return it, else fail.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
834
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
835 Stage 3 picks up from where stage 2 left off, and tries hard to return
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
836 *SOME* device type in all possible situations, modulo the DEVTYPE-SPEC
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
837 flag. \(DEVTYPE-SPEC and CURRENT-DEVICE are the same as in
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
838 `derive-domain-from-locale'.)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
839
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
840 Specifically:
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
841
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
842 \(a) if no matching devices, return the selected device's type.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
843 \(b) if more than device type and the selected device's type is
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
844 listed, use it.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
845 \(c) else, pick one of the device types (currently the first).
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
846
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
847 This will never return a device type that's incompatible with the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
848 DEVTYPE-SPEC flag; thus, it may return nil."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
849 (or try-stages (setq try-stages 1))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
850 (if (eq try-stages t) (setq try-stages 3))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
851 (check-argument-range try-stages 1 3)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
852 (flet ((delete-wrong-type (x)
3926
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
853 (delete-if-not
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
854 #'(lambda (y)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
855 (device-type-matches-spec y devtype-spec))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
856 x)))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
857 (let ((both (intersection
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
858 (if current-device
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
859 (list (device-type current-device))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
860 (device-type-list))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
861 (canonicalize-tag-set tag-set))))
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
862 ;; shouldn't be more than one (will fail), but whatever
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
863 (if both (first (delete-wrong-type both))
3926
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
864 (and (>= try-stages 2)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
865 ;; no device types mentioned. try the hard way,
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
866 ;; i.e. check each existing device (or the
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
867 ;; supplied device) to see if it will pass muster.
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
868 ;;
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
869 ;; Further checking is not relevant if current-device was
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
870 ;; supplied.
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
871 (not current-device)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
872 (let ((okdevs
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
873 (delete-wrong-type
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
874 (delete-duplicates
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
875 (mapcan
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
876 #'(lambda (dev)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
877 (and (device-matches-specifier-tag-set-p
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
878 dev tag-set)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
879 (list (device-type dev))))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
880 (if current-device
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
881 (list current-device)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
882 (device-list))))))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
883 (devtype (cond ((or (null devtype-spec)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
884 (eq devtype-spec 'window-system))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
885 (let ((dev (derive-domain-from-locale
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
886 'global devtype-spec
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
887 current-device)))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
888 (and dev (device-type dev))))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
889 (t devtype-spec))))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
890 (cond ((= 1 (length okdevs)) (car okdevs))
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
891 ((< try-stages 3) nil)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
892 ((null okdevs) devtype)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
893 ((memq devtype okdevs) devtype)
74b10360eef9 [xemacs-hg @ 2007-04-29 11:15:01 by aidan]
aidan
parents: 3061
diff changeset
894 (t (car okdevs)))))))))
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
895
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
896 ;; Sheesh, the things you do to get "intuitive" behavior.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
897 (defun derive-device-type-from-locale-and-tag-set (locale tag-set
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
898 &optional devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
899 current-device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
900 "Try to derive a device type from a locale and tag set.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
901
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
902 If the locale is a domain, use the domain's device type. Else, if the tag
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
903 set uniquely specifies a device type, use it. Else, if a buffer is given,
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
904 find a window visiting the buffer, and if any, use its device type.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
905 Finally, go back to the tag set and \"try harder\" -- if the selected
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
906 device matches the tag set, use its device type, else use some valid device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
907 type from the tag set.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
908
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
909 DEVTYPE-SPEC and CURRENT-DEVICE as in `derive-domain-from-locale'."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
910 (cond ((valid-specifier-domain-p locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
911 ;; if locale is a domain, then it must match DEVTYPE-SPEC,
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
912 ;; or we exit immediately with nil.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
913 (device-type-matches-spec (device-type (dfw-device locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
914 devtype-spec))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
915 ((derive-device-type-from-tag-set tag-set 2 devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
916 current-device))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
917 ((and (bufferp locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
918 (let ((win (get-buffer-window locale t devtype-spec)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
919 (and win (device-type (dfw-device win))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
920 ((derive-device-type-from-tag-set tag-set t devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
921 current-device))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
922
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
923 (defun derive-specifier-specs-from-locale (specifier locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
924 &optional devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
925 current-device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
926 global-use-fallback)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
927 "Heuristically find the specs of a specifier in a locale.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
928
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
929 This tries to find some reasonable instantiators that are most likely to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
930 correspond to the specifier's \"value\" (i.e. instance) in a particular
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
931 locale, even when the user has not specifically set any such instantiators.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
932 This is useful for functions that want to modify the instance of a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
933 specifier in a particular locale, and only in that locale.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
934
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
935 Keep in mind that this is a heuristic (i.e. kludge) function, and that it
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
936 may not always give the right results, since the operation is not
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
937 technically well-defined in many cases! (See `derive-domain-from-locale'.)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
938
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
939 DEVTYPE-SPEC and CURRENT-DEVICE are as in `derive-domain-from-locale'.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
940
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
941 The return value is an inst-list, i.e.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
942
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
943 ((TAG-SET . INSTANTIATOR) ...)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
944
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
945 More specifically, if there is already a spec in the locale, it's just
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
946 returned. Otherwise, if LOCALE is `global', `all', or nil: If
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
947 GLOBAL-USE-FALLBACK is non-nil, the fallback is fetched, and returned, with
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
948 `default' added to the tag set; else, we use CURRENT-DEVICE (defaulting to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
949 the selected device) as a domain and proceed as in the following. If
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
950 LOCALE is a domain (window, frame, device), the specifier's instance in
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
951 that domain is computed, and converted back to an instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
952 \(`instance-to-instantiator'). Else, if LOCALE is a buffer, we use
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
953 `derive-domain-from-locale' to heuristically get a likely domain, and
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
954 proceed as if LOCALE were a domain."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
955 (if (memq locale '(all nil)) (setq locale 'global))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
956 (let ((current (specifier-spec-list specifier locale)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
957 (if current (cdar current)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
958 ;; case 1: a global locale, fallbacks
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
959 (cond ((and (eq locale 'global) global-use-fallback)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
960 ;; if nothing there globally, retrieve the fallback.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
961 ;; this is either an inst-list or a specifier. in the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
962 ;; latter case, we need to recursively retrieve its
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
963 ;; fallback.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
964 (let (sofar
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
965 (fallback (specifier-fallback specifier)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
966 (while (specifierp fallback)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
967 (setq sofar (nconc sofar
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
968 (cdar (specifier-spec-list fallback
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
969 'global))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
970 (setq fallback (specifier-fallback fallback)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
971 (add-tag-to-inst-list (nconc sofar fallback) 'default)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
972 (t
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
973 (let (domain)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
974 ;; case 2: window, frame, device locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
975 (cond ((eq locale 'global)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
976 (setq domain (or current-device (selected-device))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
977 ((valid-specifier-domain-p locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
978 (setq domain locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
979 ;; case 3: buffer locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
980 ((bufferp locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
981 (setq domain (derive-domain-from-locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
982 locale devtype-spec current-device)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
983 (t nil))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
984 ;; retrieve an instance, convert back to instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
985 (when domain
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
986 (let ((inst
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
987 (instance-to-instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
988 (specifier-instance specifier domain))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
989 (list (cons nil inst))))))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
990
4489
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
991 ;; Character 160 (octal 0240) displays incorrectly under some X
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
992 ;; installations apparently due to a universally crocked font width
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
993 ;; specification. Display it as a space since that's what's expected.
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
994 ;;
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
995 ;; (make-char-table 'generic) instead of (make-display-table) because
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
996 ;; make-display-table isn't dumped, and this file is.
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
997 ;;
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
998 ;; We also want the global display table to be actually globally
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
999 ;; initialised; that's why this is here, and not in x-init.el, these days.
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
1000
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
1001 (set-specifier current-display-table
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
1002 #s(char-table type generic data (?\xA0 ?\x20))
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
1003 'global)
b75b075a9041 Support displaying invalid UTF-8 in language-environment-specific ways.
Aidan Kehoe <kehoea@parhasard.net>
parents: 4194
diff changeset
1004
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1005 ;;; specifier.el ends here