Mercurial > hg > xemacs-beta
diff src/specifier.c @ 280:7df0dd720c89 r21-0b38
Import from CVS: tag r21-0b38
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:32:22 +0200 |
parents | 6330739388db |
children | 558f606b08ae |
line wrap: on
line diff
--- a/src/specifier.c Mon Aug 13 10:31:30 2007 +0200 +++ b/src/specifier.c Mon Aug 13 10:32:22 2007 +0200 @@ -24,7 +24,9 @@ /* Design by Ben Wing; Original version by Chuck Thompson; - rewritten by Ben Wing */ + rewritten by Ben Wing; + Magic specifiers by Kirill Katsnelson; +*/ #include <config.h> #include "lisp.h" @@ -69,14 +71,14 @@ /* Do NOT mark through this, or specifiers will never be GC'd. */ static Lisp_Object Vall_specifiers; -static Lisp_Object Vreveal_ghoste_specifiers; +static Lisp_Object Vunlock_ghost_specifiers; /* #### The purpose of this is to check for inheritance loops in specifiers that can inherit from other specifiers, but it's not yet implemented. #### Look into this for 19.14. */ -static Lisp_Object_dynarr current_specifiers; +/* static Lisp_Object_dynarr current_specifiers; */ static void recompute_cached_specifier_everywhere (Lisp_Object specifier); @@ -303,8 +305,8 @@ internal_equal (s1->device_specs, s2->device_specs, depth) && internal_equal (s1->frame_specs, s2->frame_specs, depth) && internal_equal (s1->window_specs, s2->window_specs, depth) && - internal_equal (s1->buffer_specs, s2->buffer_specs, depth)); - /* #### Why do not compare fallbacks here? */ + internal_equal (s1->buffer_specs, s2->buffer_specs, depth) && + internal_equal (s1->fallback, s2->fallback, depth)); if (retval && HAS_SPECMETH_P (s1, equal)) retval = SPECMETH (s1, equal, (o1, o2, depth - 1)); @@ -584,8 +586,8 @@ signal_simple_error ("Invalid specifier locale or locale type", locale); } -DEFUN ("specifier-locale-type-from-locale", - Fspecifier_locale_type_from_locale, 1, 1, 0, /* +DEFUN ("specifier-locale-type-from-locale", Fspecifier_locale_type_from_locale, + 1, 1, 0, /* Given a specifier LOCALE, return its type. */ (locale)) @@ -938,8 +940,8 @@ } } -DEFUN ("device-matching-specifier-tag-list", - Fdevice_matching_specifier_tag_list, 0, 1, 0, /* +DEFUN ("device-matching-specifier-tag-list", Fdevice_matching_specifier_tag_list, + 0, 1, 0, /* Return a list of all specifier tags matching DEVICE. DEVICE defaults to the selected device if omitted. */ @@ -1237,7 +1239,7 @@ return SPEC_PREPEND; /* not reached */ } -/* Given a specifier object SPEC, return its bodily specifier for a +/* Given a specifier object SPEC, return bodily specifier if SPEC is a ghost specifier, otherwise return the object itself */ static Lisp_Object @@ -1247,36 +1249,35 @@ ? XSPECIFIER(spec)->magic_parent : spec); } -/* Given a specifier object SPEC, return a specifier to be operated on - by external lisp function. This is a ghost specifier for a magic - specifier when and only when Vreveal_ghoste_specifiers is non-nil, - otherwise SPEC itself. +/* Signal error if (specifier SPEC is read-only. + Read only are ghost specifiers unless Vunlock_ghost_specifiers is + non-nil. All other specifiers are read-write. */ -static Lisp_Object -maybe_ghost_specifier (Lisp_Object spec) +static void +check_modifiable_specifier (Lisp_Object spec) { - return (!NILP (Vreveal_ghoste_specifiers) - && BODILY_SPECIFIER_P (XSPECIFIER (spec)) - ? XSPECIFIER(spec)->fallback : spec); + if (NILP (Vunlock_ghost_specifiers) + && GHOST_SPECIFIER_P (XSPECIFIER (spec))) + signal_simple_error ("Attempt to modify read-only specifier", + list1 (spec)); } /* Helper function which unwind protects the value of - Vreveal_ghoste_specifiers, then sets it to non-nil value */ - + Vunlock_ghost_specifiers, then sets it to non-nil value */ static Lisp_Object -restore_reveal_value (Lisp_Object val) +restore_unlock_value (Lisp_Object val) { - Vreveal_ghoste_specifiers = val; + Vunlock_ghost_specifiers = val; return val; } int -reveal_ghost_specifiers_protected (void) +unlock_ghost_specifiers_protected (void) { int depth = specpdl_depth (); - record_unwind_protect (restore_reveal_value, - Vreveal_ghoste_specifiers); - Vreveal_ghoste_specifiers = Qt; + record_unwind_protect (restore_unlock_value, + Vunlock_ghost_specifiers); + Vunlock_ghost_specifiers = Qt; return depth; } @@ -1844,6 +1845,8 @@ struct gcpro gcpro1; CHECK_SPECIFIER (specifier); + check_modifiable_specifier (specifier); + locale = decode_locale (locale); check_valid_instantiator (instantiator, decode_specifier_type @@ -1856,8 +1859,7 @@ inst_list = list1 (Fcons (tag_set, instantiator)); GCPRO1 (inst_list); - specifier_add_spec (maybe_ghost_specifier (specifier), - locale, inst_list, add_meth); + specifier_add_spec (specifier, locale, inst_list, add_meth); recompute_cached_specifier_everywhere (specifier); RETURN_UNGCPRO (Qnil); } @@ -1895,6 +1897,8 @@ Lisp_Object rest; CHECK_SPECIFIER (specifier); + check_modifiable_specifier (specifier); + check_valid_spec_list (spec_list, decode_specifier_type (Fspecifier_type (specifier), ERROR_ME), @@ -1908,8 +1912,7 @@ Lisp_Object locale = XCAR (specification); Lisp_Object inst_list = XCDR (specification); - specifier_add_spec (maybe_ghost_specifier (specifier), - locale, inst_list, add_meth); + specifier_add_spec (specifier, locale, inst_list, add_meth); } recompute_cached_specifier_everywhere (specifier); return Qnil; @@ -1920,9 +1923,9 @@ Lisp_Object locale, Lisp_Object tag_set, Lisp_Object how_to_add) { - int depth = reveal_ghost_specifiers_protected (); - Fadd_spec_to_specifier (specifier, instantiator, locale, - tag_set, how_to_add); + int depth = unlock_ghost_specifiers_protected (); + Fadd_spec_to_specifier (XSPECIFIER(specifier)->fallback, + instantiator, locale, tag_set, how_to_add); unbind_to (depth, Qnil); } @@ -2013,8 +2016,7 @@ CHECK_SPECIFIER (specifier); cl.head = cl.tail = Qnil; GCPRO2 (cl.head, cl.tail); - map_specifier (maybe_ghost_specifier (specifier), - locale, specifier_spec_list_mapfun, + map_specifier (specifier, locale, specifier_spec_list_mapfun, tag_set, exact_p, &cl); UNGCPRO; return cl.head; @@ -2058,11 +2060,9 @@ tag_set = decode_specifier_tag_set (tag_set); tag_set = canonicalize_tag_set (tag_set); RETURN_UNGCPRO - (specifier_get_external_inst_list (maybe_ghost_specifier (specifier), - locale, + (specifier_get_external_inst_list (specifier, locale, locale_type_from_locale (locale), - tag_set, !NILP (exact_p), - 1, 1)); + tag_set, !NILP (exact_p), 1, 1)); } else return Fspecifier_spec_list (specifier, locale, tag_set, exact_p); @@ -2109,8 +2109,10 @@ (specifier, locale, tag_set, exact_p)) { CHECK_SPECIFIER (specifier); - map_specifier (maybe_ghost_specifier (specifier), locale, - remove_specifier_mapfun, tag_set, exact_p, 0); + check_modifiable_specifier (specifier); + + map_specifier (specifier, locale, remove_specifier_mapfun, + tag_set, exact_p, 0); recompute_cached_specifier_everywhere (specifier); return Qnil; } @@ -2119,8 +2121,9 @@ remove_ghost_specifier (Lisp_Object specifier, Lisp_Object locale, Lisp_Object tag_set, Lisp_Object exact_p) { - int depth = reveal_ghost_specifiers_protected (); - Fremove_specifier (specifier, locale, tag_set, exact_p); + int depth = unlock_ghost_specifiers_protected (); + Fremove_specifier (XSPECIFIER(specifier)->fallback, + locale, tag_set, exact_p); unbind_to (depth, Qnil); } @@ -2202,14 +2205,15 @@ else { CHECK_SPECIFIER (dest); + check_modifiable_specifier (dest); if (XSPECIFIER (dest)->methods != XSPECIFIER (specifier)->methods) error ("Specifiers not of same type"); } cl.dest = dest; GCPRO1 (dest); - map_specifier (maybe_ghost_specifier (specifier), locale, - copy_specifier_mapfun, tag_set, exact_p, &cl); + map_specifier (specifier, locale, copy_specifier_mapfun, + tag_set, exact_p, &cl); UNGCPRO; recompute_cached_specifier_everywhere (dest); return dest; @@ -2447,7 +2451,9 @@ device = domain; else /* #### dmoore - dammit, this should just signal an error or something - shouldn't it? */ + shouldn't it? + #### No. Errors are handled in Lisp primitives implementation. + Invalid domain is a design error here - kkm. */ abort (); if (NILP (buffer) && !NILP (window)) @@ -2581,8 +2587,7 @@ CHECK_SPECIFIER (specifier); domain = decode_domain (domain); - instance = specifier_instance (maybe_ghost_specifier (specifier), - Qunbound, domain, ERROR_ME, 0, + instance = specifier_instance (specifier, Qunbound, domain, ERROR_ME, 0, !NILP (no_fallback), Qzero); return UNBOUNDP (instance) ? default_ : instance; } @@ -2619,14 +2624,13 @@ ERROR_ME); domain = decode_domain (domain); - instance = specifier_instance (maybe_ghost_specifier (specifier), - matchspec, domain, ERROR_ME, + instance = specifier_instance (specifier, matchspec, domain, ERROR_ME, 0, !NILP (no_fallback), Qzero); return UNBOUNDP (instance) ? default_ : instance; } -DEFUN ("specifier-instance-from-inst-list", - Fspecifier_instance_from_inst_list, 3, 4, 0, /* +DEFUN ("specifier-instance-from-inst-list", Fspecifier_instance_from_inst_list, + 3, 4, 0, /* Attempt to convert a particular inst-list into an instance. This attempts to instantiate INST-LIST in the given DOMAIN, as if INST-LIST existed in a specification in SPECIFIER. If @@ -2644,18 +2648,17 @@ check_valid_domain (domain); check_valid_inst_list (inst_list, sp->methods, ERROR_ME); GCPRO1 (built_up_list); - built_up_list = build_up_processed_list (maybe_ghost_specifier (specifier), - domain, inst_list); + built_up_list = build_up_processed_list (specifier, domain, inst_list); if (!NILP (built_up_list)) - val = specifier_instance_from_inst_list (maybe_ghost_specifier (specifier), - Qunbound, domain, built_up_list, - ERROR_ME, 0, Qzero); + val = specifier_instance_from_inst_list (specifier, Qunbound, domain, + built_up_list, ERROR_ME, + 0, Qzero); UNGCPRO; return UNBOUNDP (val) ? default_ : val; } -DEFUN ("specifier-matching-instance-from-inst-list", - Fspecifier_matching_instance_from_inst_list, 4, 5, 0, /* +DEFUN ("specifier-matching-instance-from-inst-list", Fspecifier_matching_instance_from_inst_list, + 4, 5, 0, /* Attempt to convert a particular inst-list into an instance. This attempts to instantiate INST-LIST in the given DOMAIN \(as if INST-LIST existed in a specification in SPECIFIER), @@ -2679,12 +2682,11 @@ check_valid_domain (domain); check_valid_inst_list (inst_list, sp->methods, ERROR_ME); GCPRO1 (built_up_list); - built_up_list = build_up_processed_list (maybe_ghost_specifier (specifier), - domain, inst_list); + built_up_list = build_up_processed_list (specifier, domain, inst_list); if (!NILP (built_up_list)) - val = specifier_instance_from_inst_list (maybe_ghost_specifier (specifier), - matchspec, domain, built_up_list, - ERROR_ME, 0, Qzero); + val = specifier_instance_from_inst_list (specifier, matchspec, domain, + built_up_list, ERROR_ME, + 0, Qzero); UNGCPRO; return UNBOUNDP (val) ? default_ : val; } @@ -3130,6 +3132,6 @@ Vuser_defined_tags = Qnil; staticpro (&Vuser_defined_tags); - Vreveal_ghoste_specifiers = Qnil; - staticpro (&Vreveal_ghoste_specifiers); + Vunlock_ghost_specifiers = Qnil; + staticpro (&Vunlock_ghost_specifiers); }