comparison src/specifier.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
39 #include "window.h" 39 #include "window.h"
40 #include "chartab.h" 40 #include "chartab.h"
41 #include "rangetab.h" 41 #include "rangetab.h"
42 42
43 Lisp_Object Qspecifierp; 43 Lisp_Object Qspecifierp;
44 Lisp_Object Qprepend, Qappend, Qremove_tag_set_prepend, Qremove_tag_set_append; 44 Lisp_Object Qremove_tag_set_prepend, Qremove_tag_set_append;
45 Lisp_Object Qremove_locale, Qremove_locale_type, Qremove_all; 45 Lisp_Object Qremove_locale, Qremove_locale_type;
46 Lisp_Object Qfallback;
47
48 /* Qinteger, Qboolean, Qgeneric defined in general.c. */
49 Lisp_Object Qnatnum;
50 46
51 Lisp_Object Qconsole_type, Qdevice_class; 47 Lisp_Object Qconsole_type, Qdevice_class;
48
49 Lisp_Object Qspecifier_syntax_error;
50 Lisp_Object Qspecifier_argument_error;
51 Lisp_Object Qspecifier_change_error;
52 52
53 static Lisp_Object Vuser_defined_tags; 53 static Lisp_Object Vuser_defined_tags;
54 54
55 typedef struct specifier_type_entry specifier_type_entry; 55 typedef struct specifier_type_entry specifier_type_entry;
56 struct specifier_type_entry 56 struct specifier_type_entry
66 66
67 static specifier_type_entry_dynarr *the_specifier_type_entry_dynarr; 67 static specifier_type_entry_dynarr *the_specifier_type_entry_dynarr;
68 68
69 static const struct lrecord_description ste_description_1[] = { 69 static const struct lrecord_description ste_description_1[] = {
70 { XD_LISP_OBJECT, offsetof (specifier_type_entry, symbol) }, 70 { XD_LISP_OBJECT, offsetof (specifier_type_entry, symbol) },
71 { XD_STRUCT_PTR, offsetof (specifier_type_entry, meths), 1, &specifier_methods_description }, 71 { XD_STRUCT_PTR, offsetof (specifier_type_entry, meths), 1,
72 &specifier_methods_description },
72 { XD_END } 73 { XD_END }
73 }; 74 };
74 75
75 static const struct struct_description ste_description = { 76 static const struct struct_description ste_description = {
76 sizeof (specifier_type_entry), 77 sizeof (specifier_type_entry),
352 internal_hash (s->frame_specs, depth + 1), 353 internal_hash (s->frame_specs, depth + 1),
353 internal_hash (s->buffer_specs, depth + 1)); 354 internal_hash (s->buffer_specs, depth + 1));
354 } 355 }
355 356
356 static size_t 357 static size_t
357 sizeof_specifier (CONST void *header) 358 sizeof_specifier (const void *header)
358 { 359 {
359 if (GHOST_SPECIFIER_P ((Lisp_Specifier *) header)) 360 if (GHOST_SPECIFIER_P ((Lisp_Specifier *) header))
360 return offsetof (Lisp_Specifier, data); 361 return offsetof (Lisp_Specifier, data);
361 else 362 else
362 { 363 {
363 CONST Lisp_Specifier *p = (CONST Lisp_Specifier *) header; 364 const Lisp_Specifier *p = (const Lisp_Specifier *) header;
364 return offsetof (Lisp_Specifier, data) + p->methods->extra_data_size; 365 return offsetof (Lisp_Specifier, data) + p->methods->extra_data_size;
365 } 366 }
366 } 367 }
367 368
368 static const struct lrecord_description specifier_methods_description_1[] = { 369 static const struct lrecord_description specifier_methods_description_1[] = {
383 sizeof (struct specifier_caching), 384 sizeof (struct specifier_caching),
384 specifier_caching_description_1 385 specifier_caching_description_1
385 }; 386 };
386 387
387 static const struct lrecord_description specifier_description[] = { 388 static const struct lrecord_description specifier_description[] = {
388 { XD_STRUCT_PTR, offsetof (Lisp_Specifier, methods), 1, &specifier_methods_description }, 389 { XD_STRUCT_PTR, offsetof (Lisp_Specifier, methods), 1,
390 &specifier_methods_description },
389 { XD_LO_LINK, offsetof (Lisp_Specifier, next_specifier) }, 391 { XD_LO_LINK, offsetof (Lisp_Specifier, next_specifier) },
390 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, global_specs) }, 392 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, global_specs) },
391 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, device_specs) }, 393 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, device_specs) },
392 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, frame_specs) }, 394 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, frame_specs) },
393 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, window_specs) }, 395 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, window_specs) },
394 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, buffer_specs) }, 396 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, buffer_specs) },
395 { XD_STRUCT_PTR, offsetof (Lisp_Specifier, caching), 1, &specifier_caching_description }, 397 { XD_STRUCT_PTR, offsetof (Lisp_Specifier, caching), 1,
398 &specifier_caching_description },
396 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, magic_parent) }, 399 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, magic_parent) },
397 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, fallback) }, 400 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, fallback) },
398 { XD_SPECIFIER_END } 401 { XD_SPECIFIER_END }
399 }; 402 };
400 403
423 { 426 {
424 if (EQ (type, Dynarr_at (the_specifier_type_entry_dynarr, i).symbol)) 427 if (EQ (type, Dynarr_at (the_specifier_type_entry_dynarr, i).symbol))
425 return Dynarr_at (the_specifier_type_entry_dynarr, i).meths; 428 return Dynarr_at (the_specifier_type_entry_dynarr, i).meths;
426 } 429 }
427 430
428 maybe_signal_simple_error ("Invalid specifier type", type, 431 maybe_signal_type_error (Qspecifier_argument_error, "Invalid specifier type",
429 Qspecifier, errb); 432 type, Qspecifier, errb);
430 433
431 return 0; 434 return 0;
432 } 435 }
433 436
434 static int 437 static int
530 DEFUN ("make-specifier", Fmake_specifier, 1, 1, 0, /* 533 DEFUN ("make-specifier", Fmake_specifier, 1, 1, 0, /*
531 Return a new specifier object of type TYPE. 534 Return a new specifier object of type TYPE.
532 535
533 A specifier is an object that can be used to keep track of a property 536 A specifier is an object that can be used to keep track of a property
534 whose value can be per-buffer, per-window, per-frame, or per-device, 537 whose value can be per-buffer, per-window, per-frame, or per-device,
535 and can further be restricted to a particular console-type or device-class. 538 and can further be restricted to a particular console-type or
536 Specifiers are used, for example, for the various built-in properties of a 539 device-class. Specifiers are used, for example, for the various
537 face; this allows a face to have different values in different frames, 540 built-in properties of a face; this allows a face to have different
538 buffers, etc. For more information, see `specifier-instance', 541 values in different frames, buffers, etc.
542
543 When speaking of the value of a specifier, it is important to
544 distinguish between the *setting* of a specifier, called an
545 \"instantiator\", and the *actual value*, called an \"instance\". You
546 put various possible instantiators (i.e. settings) into a specifier
547 and associate them with particular locales (buffer, window, frame,
548 device, global), and then the instance (i.e. actual value) is
549 retrieved in a specific domain (window, frame, device) by looking
550 through the possible instantiators (i.e. settings). This process is
551 called \"instantiation\".
552
553 To put settings into a specifier, use `set-specifier', or the
554 lower-level functions `add-spec-to-specifier' and
555 `add-spec-list-to-specifier'. You can also temporarily bind a setting
556 to a specifier using `let-specifier'. To retrieve settings, use
557 `specifier-specs', or its lower-level counterpart
558 `specifier-spec-list'. To determine the actual value, use
559 `specifier-instance'.
560
561 For more information, see `set-specifier', `specifier-instance',
539 `specifier-specs', and `add-spec-to-specifier'; or, for a detailed 562 `specifier-specs', and `add-spec-to-specifier'; or, for a detailed
540 description of specifiers, including how they are instantiated over a 563 description of specifiers, including how exactly the instantiation
541 particular domain (i.e. how their value in that domain is determined), 564 process works, see the chapter on specifiers in the XEmacs Lisp
542 see the chapter on specifiers in the XEmacs Lisp Reference Manual. 565 Reference Manual.
543 566
544 TYPE specifies the particular type of specifier, and should be one of 567 TYPE specifies the particular type of specifier, and should be one of
545 the symbols 'generic, 'integer, 'boolean, 'color, 'font, 'image, 568 the symbols 'generic, 'integer, 'natnum, 'boolean, 'color, 'font,
546 'face-boolean, or 'toolbar. 569 'image, 'face-boolean, 'display-table, 'gutter, 'gutter-size,
547 570 'gutter-visible or 'toolbar.
548 For more information on particular types of specifiers, see the functions 571
549 `generic-specifier-p', `integer-specifier-p', `boolean-specifier-p', 572 For more information on particular types of specifiers, see the
550 `color-specifier-p', `font-specifier-p', `image-specifier-p', 573 functions `make-generic-specifier', `make-integer-specifier',
551 `face-boolean-specifier-p', and `toolbar-specifier-p'. 574 `make-natnum-specifier', `make-boolean-specifier',
575 `make-color-specifier', `make-font-specifier', `make-image-specifier',
576 `make-face-boolean-specifier', `make-gutter-size-specifier',
577 `make-gutter-visible-specifier', `default-toolbar', `default-gutter',
578 and `current-display-table'.
552 */ 579 */
553 (type)) 580 (type))
554 { 581 {
555 /* This function can GC */ 582 /* This function can GC */
556 struct specifier_methods *meths = decode_specifier_type (type, 583 struct specifier_methods *meths = decode_specifier_type (type, ERROR_ME);
557 ERROR_ME);
558 584
559 return make_specifier (meths); 585 return make_specifier (meths);
560 } 586 }
561 587
562 DEFUN ("specifierp", Fspecifierp, 1, 1, 0, /* 588 DEFUN ("specifierp", Fspecifierp, 1, 1, 0, /*
605 } 631 }
606 632
607 DEFUN ("valid-specifier-domain-p", Fvalid_specifier_domain_p, 1, 1, 0, /* 633 DEFUN ("valid-specifier-domain-p", Fvalid_specifier_domain_p, 1, 1, 0, /*
608 Return t if DOMAIN is a valid specifier domain. 634 Return t if DOMAIN is a valid specifier domain.
609 A domain is used to instance a specifier (i.e. determine the specifier's 635 A domain is used to instance a specifier (i.e. determine the specifier's
610 value in that domain). Valid domains are windows, frames, and devices. 636 value in that domain). Valid domains are image instances, windows, frames,
611 \(nil is not valid.) 637 and devices. \(nil is not valid.) image instances are pseudo-domains since
638 instantiation will actually occur in the window the image instance itself is
639 instantiated in.
612 */ 640 */
613 (domain)) 641 (domain))
614 { 642 {
615 /* This cannot GC. */ 643 /* This cannot GC. */
616 return ((DEVICEP (domain) && DEVICE_LIVE_P (XDEVICE (domain))) || 644 return ((DEVICEP (domain) && DEVICE_LIVE_P (XDEVICE (domain))) ||
617 (FRAMEP (domain) && FRAME_LIVE_P (XFRAME (domain))) || 645 (FRAMEP (domain) && FRAME_LIVE_P (XFRAME (domain))) ||
618 (WINDOWP (domain) && WINDOW_LIVE_P (XWINDOW (domain)))) 646 (WINDOWP (domain) && WINDOW_LIVE_P (XWINDOW (domain))) ||
647 /* #### get image instances out of domains! */
648 IMAGE_INSTANCEP (domain))
619 ? Qt : Qnil; 649 ? Qt : Qnil;
620 } 650 }
621 651
622 DEFUN ("valid-specifier-locale-type-p", Fvalid_specifier_locale_type_p, 1, 1, 0, /* 652 DEFUN ("valid-specifier-locale-type-p", Fvalid_specifier_locale_type_p, 1, 1, 0,
653 /*
623 Given a specifier LOCALE-TYPE, return non-nil if it is valid. 654 Given a specifier LOCALE-TYPE, return non-nil if it is valid.
624 Valid locale types are 'global, 'device, 'frame, 'window, and 'buffer. 655 Valid locale types are 'global, 'device, 'frame, 'window, and 'buffer.
625 \(Note, however, that in functions that accept either a locale or a locale 656 \(Note, however, that in functions that accept either a locale or a locale
626 type, 'global is considered an individual locale.) 657 type, 'global is considered an individual locale.)
627 */ 658 */
641 /* This cannot GC. */ 672 /* This cannot GC. */
642 if (EQ (locale, Qall) || 673 if (EQ (locale, Qall) ||
643 !NILP (Fvalid_specifier_locale_p (locale)) || 674 !NILP (Fvalid_specifier_locale_p (locale)) ||
644 !NILP (Fvalid_specifier_locale_type_p (locale))) 675 !NILP (Fvalid_specifier_locale_type_p (locale)))
645 return; 676 return;
646 signal_simple_error ("Invalid specifier locale or locale type", locale); 677 signal_type_error (Qspecifier_argument_error,
678 "Invalid specifier locale or locale type", locale);
647 } 679 }
648 680
649 DEFUN ("specifier-locale-type-from-locale", Fspecifier_locale_type_from_locale, 681 DEFUN ("specifier-locale-type-from-locale", Fspecifier_locale_type_from_locale,
650 1, 1, 0, /* 682 1, 1, 0, /*
651 Given a specifier LOCALE, return its type. 683 Given a specifier LOCALE, return its type.
652 */ 684 */
653 (locale)) 685 (locale))
654 { 686 {
655 /* This cannot GC. */ 687 /* This cannot GC. */
656 if (NILP (Fvalid_specifier_locale_p (locale))) 688 if (NILP (Fvalid_specifier_locale_p (locale)))
657 signal_simple_error ("Invalid specifier locale", locale); 689 signal_type_error (Qspecifier_argument_error, "Invalid specifier locale",
690 locale);
658 if (DEVICEP (locale)) return Qdevice; 691 if (DEVICEP (locale)) return Qdevice;
659 if (FRAMEP (locale)) return Qframe; 692 if (FRAMEP (locale)) return Qframe;
660 if (WINDOWP (locale)) return Qwindow; 693 if (WINDOWP (locale)) return Qwindow;
661 if (BUFFERP (locale)) return Qbuffer; 694 if (BUFFERP (locale)) return Qbuffer;
662 assert (EQ (locale, Qglobal)); 695 assert (EQ (locale, Qglobal));
670 if (NILP (locale)) 703 if (NILP (locale))
671 return Qglobal; 704 return Qglobal;
672 else if (!NILP (Fvalid_specifier_locale_p (locale))) 705 else if (!NILP (Fvalid_specifier_locale_p (locale)))
673 return locale; 706 return locale;
674 else 707 else
675 signal_simple_error ("Invalid specifier locale", locale); 708 signal_type_error (Qspecifier_argument_error, "Invalid specifier locale",
709 locale);
676 710
677 return Qnil; 711 return Qnil;
678 } 712 }
679 713
680 static enum spec_locale_type 714 static enum spec_locale_type
685 if (EQ (locale_type, Qdevice)) return LOCALE_DEVICE; 719 if (EQ (locale_type, Qdevice)) return LOCALE_DEVICE;
686 if (EQ (locale_type, Qframe)) return LOCALE_FRAME; 720 if (EQ (locale_type, Qframe)) return LOCALE_FRAME;
687 if (EQ (locale_type, Qwindow)) return LOCALE_WINDOW; 721 if (EQ (locale_type, Qwindow)) return LOCALE_WINDOW;
688 if (EQ (locale_type, Qbuffer)) return LOCALE_BUFFER; 722 if (EQ (locale_type, Qbuffer)) return LOCALE_BUFFER;
689 723
690 signal_simple_error ("Invalid specifier locale type", locale_type); 724 signal_type_error (Qspecifier_argument_error, "Invalid specifier locale type",
725 locale_type);
691 return LOCALE_GLOBAL; /* not reached */ 726 return LOCALE_GLOBAL; /* not reached */
692 } 727 }
693 728
694 Lisp_Object 729 Lisp_Object
695 decode_locale_list (Lisp_Object locale) 730 decode_locale_list (Lisp_Object locale)
700 { 735 {
701 return list1 (Qall); 736 return list1 (Qall);
702 } 737 }
703 else if (CONSP (locale)) 738 else if (CONSP (locale))
704 { 739 {
705 Lisp_Object elt;
706 EXTERNAL_LIST_LOOP_2 (elt, locale) 740 EXTERNAL_LIST_LOOP_2 (elt, locale)
707 check_valid_locale_or_locale_type (elt); 741 check_valid_locale_or_locale_type (elt);
708 return locale; 742 return locale;
709 } 743 }
710 else 744 else
722 756
723 static void 757 static void
724 check_valid_domain (Lisp_Object domain) 758 check_valid_domain (Lisp_Object domain)
725 { 759 {
726 if (NILP (Fvalid_specifier_domain_p (domain))) 760 if (NILP (Fvalid_specifier_domain_p (domain)))
727 signal_simple_error ("Invalid specifier domain", domain); 761 signal_type_error (Qspecifier_argument_error, "Invalid specifier domain",
728 } 762 domain);
729 763 }
730 static Lisp_Object 764
765 Lisp_Object
731 decode_domain (Lisp_Object domain) 766 decode_domain (Lisp_Object domain)
732 { 767 {
733 if (NILP (domain)) 768 if (NILP (domain))
734 return Fselected_window (Qnil); 769 return Fselected_window (Qnil);
735 check_valid_domain (domain); 770 check_valid_domain (domain);
798 { 833 {
799 /* The return value of this function must be GCPRO'd. */ 834 /* The return value of this function must be GCPRO'd. */
800 if (!NILP (Fvalid_specifier_tag_p (tag_set))) 835 if (!NILP (Fvalid_specifier_tag_p (tag_set)))
801 return list1 (tag_set); 836 return list1 (tag_set);
802 if (NILP (Fvalid_specifier_tag_set_p (tag_set))) 837 if (NILP (Fvalid_specifier_tag_set_p (tag_set)))
803 signal_simple_error ("Invalid specifier tag-set", tag_set); 838 signal_type_error (Qspecifier_argument_error, "Invalid specifier tag-set",
839 tag_set);
804 return tag_set; 840 return tag_set;
805 } 841 }
806 842
807 static Lisp_Object 843 static Lisp_Object
808 canonicalize_tag_set (Lisp_Object tag_set) 844 canonicalize_tag_set (Lisp_Object tag_set)
861 sorting by symbol name and removing duplicates.) 897 sorting by symbol name and removing duplicates.)
862 */ 898 */
863 (tag_set)) 899 (tag_set))
864 { 900 {
865 if (NILP (Fvalid_specifier_tag_set_p (tag_set))) 901 if (NILP (Fvalid_specifier_tag_set_p (tag_set)))
866 signal_simple_error ("Invalid tag set", tag_set); 902 signal_type_error (Qspecifier_argument_error, "Invalid tag set", tag_set);
867 return canonicalize_tag_set (tag_set); 903 return canonicalize_tag_set (tag_set);
868 } 904 }
869 905
870 static int 906 static int
871 device_matches_specifier_tag_set_p (Lisp_Object device, Lisp_Object tag_set) 907 device_matches_specifier_tag_set_p (Lisp_Object device, Lisp_Object tag_set)
891 } 927 }
892 928
893 return 1; 929 return 1;
894 } 930 }
895 931
896 DEFUN ("device-matches-specifier-tag-set-p", Fdevice_matches_specifier_tag_set_p, 2, 2, 0, /* 932 DEFUN ("device-matches-specifier-tag-set-p",
933 Fdevice_matches_specifier_tag_set_p, 2, 2, 0, /*
897 Return non-nil if DEVICE matches specifier tag set TAG-SET. 934 Return non-nil if DEVICE matches specifier tag set TAG-SET.
898 This means that DEVICE matches each tag in the tag set. (Every 935 This means that DEVICE matches each tag in the tag set. (Every
899 tag recognized by XEmacs has a predicate associated with it that 936 tag recognized by XEmacs has a predicate associated with it that
900 specifies which devices match it.) 937 specifies which devices match it.)
901 */ 938 */
902 (device, tag_set)) 939 (device, tag_set))
903 { 940 {
904 CHECK_LIVE_DEVICE (device); 941 CHECK_LIVE_DEVICE (device);
905 942
906 if (NILP (Fvalid_specifier_tag_set_p (tag_set))) 943 if (NILP (Fvalid_specifier_tag_set_p (tag_set)))
907 signal_simple_error ("Invalid tag set", tag_set); 944 signal_type_error (Qspecifier_argument_error, "Invalid tag set", tag_set);
908 945
909 return device_matches_specifier_tag_set_p (device, tag_set) ? Qt : Qnil; 946 return device_matches_specifier_tag_set_p (device, tag_set) ? Qt : Qnil;
910 } 947 }
911 948
912 DEFUN ("define-specifier-tag", Fdefine_specifier_tag, 1, 2, 0, /* 949 DEFUN ("define-specifier-tag", Fdefine_specifier_tag, 1, 2, 0, /*
925 int recompute = 0; 962 int recompute = 0;
926 963
927 CHECK_SYMBOL (tag); 964 CHECK_SYMBOL (tag);
928 if (valid_device_class_p (tag) || 965 if (valid_device_class_p (tag) ||
929 valid_console_type_p (tag)) 966 valid_console_type_p (tag))
930 signal_simple_error ("Cannot redefine built-in specifier tags", tag); 967 signal_type_error (Qspecifier_change_error,
968 "Cannot redefine built-in specifier tags", tag);
931 /* Try to prevent common instantiators and locales from being 969 /* Try to prevent common instantiators and locales from being
932 redefined, to reduce ambiguity */ 970 redefined, to reduce ambiguity */
933 if (NILP (tag) || EQ (tag, Qt) || EQ (tag, Qall) || EQ (tag, Qglobal)) 971 if (NILP (tag) || EQ (tag, Qt) || EQ (tag, Qall) || EQ (tag, Qglobal))
934 signal_simple_error ("Cannot define nil, t, 'all, or 'global", 972 signal_type_error (Qspecifier_change_error, "Cannot define nil, t, 'all, or 'global",
935 tag); 973 tag);
936 assoc = assq_no_quit (tag, Vuser_defined_tags); 974 assoc = assq_no_quit (tag, Vuser_defined_tags);
937 if (NILP (assoc)) 975 if (NILP (assoc))
938 { 976 {
939 recompute = 1; 977 recompute = 1;
940 Vuser_defined_tags = Fcons (Fcons (tag, predicate), Vuser_defined_tags); 978 Vuser_defined_tags = Fcons (Fcons (tag, predicate), Vuser_defined_tags);
1003 else 1041 else
1004 XCDR (XCAR (rest2)) = !NILP (call1 (predicate, device)) ? Qt : Qnil; 1042 XCDR (XCAR (rest2)) = !NILP (call1 (predicate, device)) ? Qt : Qnil;
1005 } 1043 }
1006 } 1044 }
1007 1045
1008 DEFUN ("device-matching-specifier-tag-list", Fdevice_matching_specifier_tag_list, 1046 DEFUN ("device-matching-specifier-tag-list",
1047 Fdevice_matching_specifier_tag_list,
1009 0, 1, 0, /* 1048 0, 1, 0, /*
1010 Return a list of all specifier tags matching DEVICE. 1049 Return a list of all specifier tags matching DEVICE.
1011 DEVICE defaults to the selected device if omitted. 1050 DEVICE defaults to the selected device if omitted.
1012 */ 1051 */
1013 (device)) 1052 (device))
1059 { 1098 {
1060 /* The return value of this function must be GCPRO'd. */ 1099 /* The return value of this function must be GCPRO'd. */
1061 CHECK_SYMBOL (tag); 1100 CHECK_SYMBOL (tag);
1062 1101
1063 if (NILP (Fvalid_specifier_tag_p (tag))) 1102 if (NILP (Fvalid_specifier_tag_p (tag)))
1064 signal_simple_error ("Invalid specifier tag", tag); 1103 signal_type_error (Qspecifier_argument_error, "Invalid specifier tag",
1104 tag);
1065 1105
1066 /* Make up some predicates for the built-in types */ 1106 /* Make up some predicates for the built-in types */
1067 1107
1068 if (valid_console_type_p (tag)) 1108 if (valid_console_type_p (tag))
1069 return list3 (Qlambda, list1 (Qdevice), 1109 return list3 (Qlambda, list1 (Qdevice),
1186 { 1226 {
1187 Lisp_Object inst_pair, tag_set; 1227 Lisp_Object inst_pair, tag_set;
1188 1228
1189 if (!CONSP (rest)) 1229 if (!CONSP (rest))
1190 { 1230 {
1191 maybe_signal_simple_error ("Invalid instantiator list", inst_list, 1231 maybe_signal_type_error (Qspecifier_syntax_error,
1232 "Invalid instantiator list", inst_list,
1192 Qspecifier, errb); 1233 Qspecifier, errb);
1193 return Qnil; 1234 return Qnil;
1194 } 1235 }
1195 if (!CONSP (inst_pair = XCAR (rest))) 1236 if (!CONSP (inst_pair = XCAR (rest)))
1196 { 1237 {
1197 maybe_signal_simple_error ("Invalid instantiator pair", inst_pair, 1238 maybe_signal_type_error (Qspecifier_syntax_error,
1239 "Invalid instantiator pair", inst_pair,
1198 Qspecifier, errb); 1240 Qspecifier, errb);
1199 return Qnil; 1241 return Qnil;
1200 } 1242 }
1201 if (NILP (Fvalid_specifier_tag_set_p (tag_set = XCAR (inst_pair)))) 1243 if (NILP (Fvalid_specifier_tag_set_p (tag_set = XCAR (inst_pair))))
1202 { 1244 {
1203 maybe_signal_simple_error ("Invalid specifier tag", tag_set, 1245 maybe_signal_type_error (Qspecifier_syntax_error,
1246 "Invalid specifier tag", tag_set,
1204 Qspecifier, errb); 1247 Qspecifier, errb);
1205 return Qnil; 1248 return Qnil;
1206 } 1249 }
1207 1250
1208 if (NILP (check_valid_instantiator (XCDR (inst_pair), meths, errb))) 1251 if (NILP (check_valid_instantiator (XCDR (inst_pair), meths, errb)))
1241 LIST_LOOP (rest, spec_list) 1284 LIST_LOOP (rest, spec_list)
1242 { 1285 {
1243 Lisp_Object spec, locale; 1286 Lisp_Object spec, locale;
1244 if (!CONSP (rest) || !CONSP (spec = XCAR (rest))) 1287 if (!CONSP (rest) || !CONSP (spec = XCAR (rest)))
1245 { 1288 {
1246 maybe_signal_simple_error ("Invalid specification list", spec_list, 1289 maybe_signal_type_error (Qspecifier_syntax_error,
1290 "Invalid specification list", spec_list,
1247 Qspecifier, errb); 1291 Qspecifier, errb);
1248 return Qnil; 1292 return Qnil;
1249 } 1293 }
1250 if (NILP (Fvalid_specifier_locale_p (locale = XCAR (spec)))) 1294 if (NILP (Fvalid_specifier_locale_p (locale = XCAR (spec))))
1251 { 1295 {
1252 maybe_signal_simple_error ("Invalid specifier locale", locale, 1296 maybe_signal_type_error (Qspecifier_syntax_error,
1297 "Invalid specifier locale", locale,
1253 Qspecifier, errb); 1298 Qspecifier, errb);
1254 return Qnil; 1299 return Qnil;
1255 } 1300 }
1256 1301
1257 if (NILP (check_valid_inst_list (XCDR (spec), meths, errb))) 1302 if (NILP (check_valid_inst_list (XCDR (spec), meths, errb)))
1297 if (EQ (Qremove_locale_type, how_to_add)) 1342 if (EQ (Qremove_locale_type, how_to_add))
1298 return SPEC_REMOVE_LOCALE_TYPE; 1343 return SPEC_REMOVE_LOCALE_TYPE;
1299 if (EQ (Qremove_all, how_to_add)) 1344 if (EQ (Qremove_all, how_to_add))
1300 return SPEC_REMOVE_ALL; 1345 return SPEC_REMOVE_ALL;
1301 1346
1302 signal_simple_error ("Invalid `how-to-add' flag", how_to_add); 1347 signal_type_error (Qspecifier_argument_error, "Invalid `how-to-add' flag",
1348 how_to_add);
1303 1349
1304 return SPEC_PREPEND; /* not reached */ 1350 return SPEC_PREPEND; /* not reached */
1305 } 1351 }
1306 1352
1307 /* Given a specifier object SPEC, return bodily specifier if SPEC is a 1353 /* Given a specifier object SPEC, return bodily specifier if SPEC is a
1321 static void 1367 static void
1322 check_modifiable_specifier (Lisp_Object spec) 1368 check_modifiable_specifier (Lisp_Object spec)
1323 { 1369 {
1324 if (NILP (Vunlock_ghost_specifiers) 1370 if (NILP (Vunlock_ghost_specifiers)
1325 && GHOST_SPECIFIER_P (XSPECIFIER (spec))) 1371 && GHOST_SPECIFIER_P (XSPECIFIER (spec)))
1326 signal_simple_error ("Attempt to modify read-only specifier", 1372 signal_type_error (Qspecifier_change_error,
1373 "Attempt to modify read-only specifier",
1327 list1 (spec)); 1374 list1 (spec));
1328 } 1375 }
1329 1376
1330 /* Helper function which unwind protects the value of 1377 /* Helper function which unwind protects the value of
1331 Vunlock_ghost_specifiers, then sets it to non-nil value */ 1378 Vunlock_ghost_specifiers, then sets it to non-nil value */
1733 if (add_meth == SPEC_PREPEND) 1780 if (add_meth == SPEC_PREPEND)
1734 tem = nconc2 (list_to_build_up, *orig_inst_list); 1781 tem = nconc2 (list_to_build_up, *orig_inst_list);
1735 else if (add_meth == SPEC_APPEND) 1782 else if (add_meth == SPEC_APPEND)
1736 tem = nconc2 (*orig_inst_list, list_to_build_up); 1783 tem = nconc2 (*orig_inst_list, list_to_build_up);
1737 else 1784 else
1738 abort (); 1785 {
1786 abort ();
1787 tem = Qnil;
1788 }
1739 1789
1740 *orig_inst_list = tem; 1790 *orig_inst_list = tem;
1741 1791
1742 UNGCPRO; 1792 UNGCPRO;
1743 1793
2341 intern (meths->name), Qspecifier, errb); 2391 intern (meths->name), Qspecifier, errb);
2342 return Qnil; 2392 return Qnil;
2343 } 2393 }
2344 } 2394 }
2345 2395
2346 DEFUN ("check-valid-specifier-matchspec", Fcheck_valid_specifier_matchspec, 2, 2, 0, /* 2396 DEFUN ("check-valid-specifier-matchspec", Fcheck_valid_specifier_matchspec, 2,
2397 2, 0, /*
2347 Signal an error if MATCHSPEC is invalid for SPECIFIER-TYPE. 2398 Signal an error if MATCHSPEC is invalid for SPECIFIER-TYPE.
2348 See `specifier-matching-instance' for a description of matchspecs. 2399 See `specifier-matching-instance' for a description of matchspecs.
2349 */ 2400 */
2350 (matchspec, specifier_type)) 2401 (matchspec, specifier_type))
2351 { 2402 {
2431 struct gcpro gcpro1, gcpro2; 2482 struct gcpro gcpro1, gcpro2;
2432 2483
2433 GCPRO2 (specifier, inst_list); 2484 GCPRO2 (specifier, inst_list);
2434 2485
2435 sp = XSPECIFIER (specifier); 2486 sp = XSPECIFIER (specifier);
2436 device = DFW_DEVICE (domain); 2487 device = DOMAIN_DEVICE (domain);
2437 2488
2438 if (no_quit) 2489 if (no_quit)
2439 /* The instantiate method is allowed to call eval. Since it 2490 /* The instantiate method is allowed to call eval. Since it
2440 is quite common for this function to get called from somewhere in 2491 is quite common for this function to get called from somewhere in
2441 redisplay we need to make sure that quits are ignored. Otherwise 2492 redisplay we need to make sure that quits are ignored. Otherwise
2511 2562
2512 sp = XSPECIFIER (specifier); 2563 sp = XSPECIFIER (specifier);
2513 2564
2514 /* Attempt to determine buffer, window, frame, and device from the 2565 /* Attempt to determine buffer, window, frame, and device from the
2515 domain. */ 2566 domain. */
2516 if (WINDOWP (domain)) 2567 /* #### get image instances out of domains! */
2568 if (IMAGE_INSTANCEP (domain))
2569 window = DOMAIN_WINDOW (domain);
2570 else if (WINDOWP (domain))
2517 window = domain; 2571 window = domain;
2518 else if (FRAMEP (domain)) 2572 else if (FRAMEP (domain))
2519 frame = domain; 2573 frame = domain;
2520 else if (DEVICEP (domain)) 2574 else if (DEVICEP (domain))
2521 device = domain; 2575 device = domain;
2522 else 2576 else
2523 /* #### dmoore - dammit, this should just signal an error or something 2577 /* dmoore writes: [dammit, this should just signal an error or something
2524 shouldn't it? 2578 shouldn't it?]
2525 #### No. Errors are handled in Lisp primitives implementation. 2579
2580 No. Errors are handled in Lisp primitives implementation.
2526 Invalid domain is a design error here - kkm. */ 2581 Invalid domain is a design error here - kkm. */
2527 abort (); 2582 abort ();
2528 2583
2529 if (NILP (buffer) && !NILP (window)) 2584 if (NILP (buffer) && !NILP (window))
2530 buffer = XWINDOW (window)->buffer; 2585 buffer = XWINDOW (window)->buffer;
2725 0, Qzero); 2780 0, Qzero);
2726 UNGCPRO; 2781 UNGCPRO;
2727 return UNBOUNDP (val) ? default_ : val; 2782 return UNBOUNDP (val) ? default_ : val;
2728 } 2783 }
2729 2784
2730 DEFUN ("specifier-matching-instance-from-inst-list", Fspecifier_matching_instance_from_inst_list, 2785 DEFUN ("specifier-matching-instance-from-inst-list",
2786 Fspecifier_matching_instance_from_inst_list,
2731 4, 5, 0, /* 2787 4, 5, 0, /*
2732 Attempt to convert a particular inst-list into an instance. 2788 Attempt to convert a particular inst-list into an instance.
2733 This attempts to instantiate INST-LIST in the given DOMAIN 2789 This attempts to instantiate INST-LIST in the given DOMAIN
2734 \(as if INST-LIST existed in a specification in SPECIFIER), 2790 \(as if INST-LIST existed in a specification in SPECIFIER),
2735 matching the specifications against MATCHSPEC. 2791 matching the specifications against MATCHSPEC.
2814 better be able to deal. If not, set a default so this 2870 better be able to deal. If not, set a default so this
2815 never happens or correct it in the value_changed_in_window 2871 never happens or correct it in the value_changed_in_window
2816 method. */ 2872 method. */
2817 location = (Lisp_Object *) 2873 location = (Lisp_Object *)
2818 ((char *) w + XSPECIFIER (specifier)->caching->offset_into_struct_window); 2874 ((char *) w + XSPECIFIER (specifier)->caching->offset_into_struct_window);
2875 /* #### What's the point of this check, other than to optimize image
2876 instance instantiation? Unless you specify a caching instantiate
2877 method the instantiation that specifier_instance will do will
2878 always create a new copy. Thus EQ will always fail. Unfortunately
2879 calling equal is no good either as this doesn't take into account
2880 things attached to the specifier - for instance strings on
2881 extents. --andyp */
2819 if (!EQ (newval, *location)) 2882 if (!EQ (newval, *location))
2820 { 2883 {
2821 Lisp_Object oldval = *location; 2884 Lisp_Object oldval = *location;
2822 *location = newval; 2885 *location = newval;
2823 (XSPECIFIER (specifier)->caching->value_changed_in_window) 2886 (XSPECIFIER (specifier)->caching->value_changed_in_window)
2948 is supposed to require only that the specifier type is passed, 3011 is supposed to require only that the specifier type is passed,
2949 while with this approach the actual specifier is needed.) 3012 while with this approach the actual specifier is needed.)
2950 3013
2951 What really needs to be done is to write a function 3014 What really needs to be done is to write a function
2952 `make-specifier-type' that creates new specifier types. 3015 `make-specifier-type' that creates new specifier types.
2953 #### I'll look into this for 19.14. 3016
2954 */ 3017 #### [I'll look into this for 19.14.] Well, sometime. (Currently
3018 May 2000, 21.2 is in development. 19.14 was released in June 1996.) */
2955 3019
2956 "A generic specifier is a generalized kind of specifier with user-defined\n" 3020 "A generic specifier is a generalized kind of specifier with user-defined\n"
2957 "semantics. The instantiator can be any kind of Lisp object, and the\n" 3021 "semantics. The instantiator can be any kind of Lisp object, and the\n"
2958 "instance computed from it is likewise any kind of Lisp object. The\n" 3022 "instance computed from it is likewise any kind of Lisp object. The\n"
2959 "SPECIFIER-DATA should be an alist of methods governing how the specifier\n" 3023 "SPECIFIER-DATA should be an alist of methods governing how the specifier\n"
2986 #endif /* 0 */ 3050 #endif /* 0 */
2987 3051
2988 DEFUN ("generic-specifier-p", Fgeneric_specifier_p, 1, 1, 0, /* 3052 DEFUN ("generic-specifier-p", Fgeneric_specifier_p, 1, 1, 0, /*
2989 Return non-nil if OBJECT is a generic specifier. 3053 Return non-nil if OBJECT is a generic specifier.
2990 3054
2991 A generic specifier allows any kind of Lisp object as an instantiator, 3055 See `make-generic-specifier' for a description of possible generic
2992 and returns back the Lisp object unchanged when it is instantiated. 3056 instantiators.
2993 */ 3057 */
2994 (object)) 3058 (object))
2995 { 3059 {
2996 return GENERIC_SPECIFIERP (object) ? Qt : Qnil; 3060 return GENERIC_SPECIFIERP (object) ? Qt : Qnil;
2997 } 3061 }
3009 CHECK_INT (instantiator); 3073 CHECK_INT (instantiator);
3010 } 3074 }
3011 3075
3012 DEFUN ("integer-specifier-p", Finteger_specifier_p, 1, 1, 0, /* 3076 DEFUN ("integer-specifier-p", Finteger_specifier_p, 1, 1, 0, /*
3013 Return non-nil if OBJECT is an integer specifier. 3077 Return non-nil if OBJECT is an integer specifier.
3078
3079 See `make-integer-specifier' for a description of possible integer
3080 instantiators.
3014 */ 3081 */
3015 (object)) 3082 (object))
3016 { 3083 {
3017 return INTEGER_SPECIFIERP (object) ? Qt : Qnil; 3084 return INTEGER_SPECIFIERP (object) ? Qt : Qnil;
3018 } 3085 }
3029 CHECK_NATNUM (instantiator); 3096 CHECK_NATNUM (instantiator);
3030 } 3097 }
3031 3098
3032 DEFUN ("natnum-specifier-p", Fnatnum_specifier_p, 1, 1, 0, /* 3099 DEFUN ("natnum-specifier-p", Fnatnum_specifier_p, 1, 1, 0, /*
3033 Return non-nil if OBJECT is a natnum (non-negative-integer) specifier. 3100 Return non-nil if OBJECT is a natnum (non-negative-integer) specifier.
3101
3102 See `make-natnum-specifier' for a description of possible natnum
3103 instantiators.
3034 */ 3104 */
3035 (object)) 3105 (object))
3036 { 3106 {
3037 return NATNUM_SPECIFIERP (object) ? Qt : Qnil; 3107 return NATNUM_SPECIFIERP (object) ? Qt : Qnil;
3038 } 3108 }
3045 3115
3046 static void 3116 static void
3047 boolean_validate (Lisp_Object instantiator) 3117 boolean_validate (Lisp_Object instantiator)
3048 { 3118 {
3049 if (!EQ (instantiator, Qt) && !EQ (instantiator, Qnil)) 3119 if (!EQ (instantiator, Qt) && !EQ (instantiator, Qnil))
3050 signal_simple_error ("Must be t or nil", instantiator); 3120 signal_type_error (Qspecifier_argument_error, "Must be t or nil",
3121 instantiator);
3051 } 3122 }
3052 3123
3053 DEFUN ("boolean-specifier-p", Fboolean_specifier_p, 1, 1, 0, /* 3124 DEFUN ("boolean-specifier-p", Fboolean_specifier_p, 1, 1, 0, /*
3054 Return non-nil if OBJECT is a boolean specifier. 3125 Return non-nil if OBJECT is a boolean specifier.
3126
3127 See `make-boolean-specifier' for a description of possible boolean
3128 instantiators.
3055 */ 3129 */
3056 (object)) 3130 (object))
3057 { 3131 {
3058 return BOOLEAN_SPECIFIERP (object) ? Qt : Qnil; 3132 return BOOLEAN_SPECIFIERP (object) ? Qt : Qnil;
3059 } 3133 }
3062 /* Display table specifier type */ 3136 /* Display table specifier type */
3063 /************************************************************************/ 3137 /************************************************************************/
3064 3138
3065 DEFINE_SPECIFIER_TYPE (display_table); 3139 DEFINE_SPECIFIER_TYPE (display_table);
3066 3140
3067 #define VALID_SINGLE_DISPTABLE_INSTANTIATOR_P(instantiator) \ 3141 #define VALID_SINGLE_DISPTABLE_INSTANTIATOR_P(instantiator) \
3068 (VECTORP (instantiator) \ 3142 (VECTORP (instantiator) \
3069 || (CHAR_TABLEP (instantiator) \ 3143 || (CHAR_TABLEP (instantiator) \
3070 && (XCHAR_TABLE_TYPE (instantiator) == CHAR_TABLE_TYPE_CHAR \ 3144 && (XCHAR_TABLE_TYPE (instantiator) == CHAR_TABLE_TYPE_CHAR \
3071 || XCHAR_TABLE_TYPE (instantiator) == CHAR_TABLE_TYPE_GENERIC)) \ 3145 || XCHAR_TABLE_TYPE (instantiator) == CHAR_TABLE_TYPE_GENERIC)) \
3072 || RANGE_TABLEP (instantiator)) 3146 || RANGE_TABLEP (instantiator))
3073 3147
3074 static void 3148 static void
3075 display_table_validate (Lisp_Object instantiator) 3149 display_table_validate (Lisp_Object instantiator)
3076 { 3150 {
3090 else 3164 else
3091 { 3165 {
3092 if (!VALID_SINGLE_DISPTABLE_INSTANTIATOR_P (instantiator)) 3166 if (!VALID_SINGLE_DISPTABLE_INSTANTIATOR_P (instantiator))
3093 { 3167 {
3094 lose: 3168 lose:
3095 dead_wrong_type_argument (display_table_specifier_methods->predicate_symbol, 3169 dead_wrong_type_argument
3170 (display_table_specifier_methods->predicate_symbol,
3096 instantiator); 3171 instantiator);
3097 } 3172 }
3098 } 3173 }
3099 } 3174 }
3100 3175
3101 DEFUN ("display-table-specifier-p", Fdisplay_table_specifier_p, 1, 1, 0, /* 3176 DEFUN ("display-table-specifier-p", Fdisplay_table_specifier_p, 1, 1, 0, /*
3102 Return non-nil if OBJECT is a display-table specifier. 3177 Return non-nil if OBJECT is a display-table specifier.
3178
3179 See `current-display-table' for a description of possible display-table
3180 instantiators.
3103 */ 3181 */
3104 (object)) 3182 (object))
3105 { 3183 {
3106 return DISPLAYTABLE_SPECIFIERP (object) ? Qt : Qnil; 3184 return DISPLAYTABLE_SPECIFIERP (object) ? Qt : Qnil;
3107 } 3185 }
3112 /************************************************************************/ 3190 /************************************************************************/
3113 3191
3114 void 3192 void
3115 syms_of_specifier (void) 3193 syms_of_specifier (void)
3116 { 3194 {
3117 defsymbol (&Qspecifierp, "specifierp"); 3195 INIT_LRECORD_IMPLEMENTATION (specifier);
3118 3196
3119 defsymbol (&Qconsole_type, "console-type"); 3197 DEFSYMBOL (Qspecifierp);
3120 defsymbol (&Qdevice_class, "device-class"); 3198
3121 3199 DEFSYMBOL (Qconsole_type);
3122 /* Qinteger, Qboolean, Qgeneric defined in general.c */ 3200 DEFSYMBOL (Qdevice_class);
3123 defsymbol (&Qnatnum, "natnum"); 3201
3202 /* specifier types defined in general.c. */
3124 3203
3125 DEFSUBR (Fvalid_specifier_type_p); 3204 DEFSUBR (Fvalid_specifier_type_p);
3126 DEFSUBR (Fspecifier_type_list); 3205 DEFSUBR (Fspecifier_type_list);
3127 DEFSUBR (Fmake_specifier); 3206 DEFSUBR (Fmake_specifier);
3128 DEFSUBR (Fspecifierp); 3207 DEFSUBR (Fspecifierp);
3173 /* Symbols pertaining to specifier creation. Specifiers are created 3252 /* Symbols pertaining to specifier creation. Specifiers are created
3174 in the syms_of() functions. */ 3253 in the syms_of() functions. */
3175 3254
3176 /* locales are defined in general.c. */ 3255 /* locales are defined in general.c. */
3177 3256
3178 defsymbol (&Qprepend, "prepend"); 3257 /* some how-to-add flags in general.c. */
3179 defsymbol (&Qappend, "append"); 3258 DEFSYMBOL (Qremove_tag_set_prepend);
3180 defsymbol (&Qremove_tag_set_prepend, "remove-tag-set-prepend"); 3259 DEFSYMBOL (Qremove_tag_set_append);
3181 defsymbol (&Qremove_tag_set_append, "remove-tag-set-append"); 3260 DEFSYMBOL (Qremove_locale);
3182 defsymbol (&Qremove_locale, "remove-locale"); 3261 DEFSYMBOL (Qremove_locale_type);
3183 defsymbol (&Qremove_locale_type, "remove-locale-type"); 3262
3184 defsymbol (&Qremove_all, "remove-all"); 3263 DEFERROR_STANDARD (Qspecifier_syntax_error, Qsyntax_error);
3185 3264 DEFERROR_STANDARD (Qspecifier_argument_error, Qinvalid_argument);
3186 defsymbol (&Qfallback, "fallback"); 3265 DEFERROR_STANDARD (Qspecifier_change_error, Qinvalid_change);
3187 } 3266 }
3188 3267
3189 void 3268 void
3190 specifier_type_create (void) 3269 specifier_type_create (void)
3191 { 3270 {
3207 3286
3208 INITIALIZE_SPECIFIER_TYPE (boolean, "boolean", "boolean-specifier-p"); 3287 INITIALIZE_SPECIFIER_TYPE (boolean, "boolean", "boolean-specifier-p");
3209 3288
3210 SPECIFIER_HAS_METHOD (boolean, validate); 3289 SPECIFIER_HAS_METHOD (boolean, validate);
3211 3290
3212 INITIALIZE_SPECIFIER_TYPE (display_table, "display-table", "display-table-p"); 3291 INITIALIZE_SPECIFIER_TYPE (display_table, "display-table",
3292 "display-table-p");
3213 3293
3214 SPECIFIER_HAS_METHOD (display_table, validate); 3294 SPECIFIER_HAS_METHOD (display_table, validate);
3215 } 3295 }
3216 3296
3217 void 3297 void