Mercurial > hg > xemacs-beta
diff src/specifier.c @ 272:c5d627a313b1 r21-0b34
Import from CVS: tag r21-0b34
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:28:48 +0200 |
parents | 3d6bfa290dbd |
children | 6330739388db |
line wrap: on
line diff
--- a/src/specifier.c Mon Aug 13 10:27:41 2007 +0200 +++ b/src/specifier.c Mon Aug 13 10:28:48 2007 +0200 @@ -49,9 +49,6 @@ Lisp_Object Vuser_defined_tags; -MAC_DEFINE (struct Lisp_Specifier *, MTspecmeth_or_given) -MAC_DEFINE (struct Lisp_Specifier *, MTspecifier_data) - typedef struct specifier_type_entry specifier_type_entry; struct specifier_type_entry { @@ -81,24 +78,14 @@ static void recompute_cached_specifier_everywhere (Lisp_Object specifier); +EXFUN (Fspecifier_specs, 4); +EXFUN (Fremove_specifier, 4); + /************************************************************************/ /* Specifier object methods */ /************************************************************************/ -static Lisp_Object mark_specifier (Lisp_Object, void (*) (Lisp_Object)); -static void print_specifier (Lisp_Object, Lisp_Object, int); -static int specifier_equal (Lisp_Object, Lisp_Object, int depth); -static unsigned long specifier_hash (Lisp_Object obj, int depth); -static unsigned int sizeof_specifier (CONST void *header); -static void finalize_specifier (void *header, int for_disksave); -DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("specifier", specifier, - mark_specifier, print_specifier, - finalize_specifier, - specifier_equal, specifier_hash, - sizeof_specifier, - struct Lisp_Specifier); - /* Remove dead objects from the specified assoc list. */ static Lisp_Object @@ -299,16 +286,16 @@ Vinhibit_quit = Qt; depth++; - if (s1->methods != s2->methods || - !internal_equal (s1->global_specs, s2->global_specs, depth) || - !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) || - !SPECMETH_OR_GIVEN (s1, equal, (o1, o2, depth - 1), 1)) - retval = 0; - else - retval = 1; + retval = + (s1->methods == s2->methods && + internal_equal (s1->global_specs, s2->global_specs, depth) && + 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)); + + if (retval && HAS_SPECMETH_P (s1, equal)) + retval = SPECMETH (s1, equal, (o1, o2, depth - 1)); Vinhibit_quit = old_inhibit_quit; return retval; @@ -322,20 +309,27 @@ /* specifier hashing is a bit problematic because there are so many places where data can be stored. We pick what are perhaps the most likely places where interesting stuff will be. */ - return HASH5 (SPECMETH_OR_GIVEN (s, hash, (obj, depth), 0), + return HASH5 ((HAS_SPECMETH_P (s, hash) ? + SPECMETH (s, hash, (obj, depth)) : 0), (unsigned long) s->methods, internal_hash (s->global_specs, depth + 1), - internal_hash (s->frame_specs, depth + 1), + internal_hash (s->frame_specs, depth + 1), internal_hash (s->buffer_specs, depth + 1)); } -static unsigned int +static size_t sizeof_specifier (CONST void *header) { CONST struct Lisp_Specifier *p = (CONST struct Lisp_Specifier *) header; return sizeof (*p) + p->methods->extra_data_size - 1; } +DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("specifier", specifier, + mark_specifier, print_specifier, + finalize_specifier, + specifier_equal, specifier_hash, + sizeof_specifier, + struct Lisp_Specifier); /************************************************************************/ /* Creating specifiers */ @@ -361,9 +355,7 @@ static int valid_specifier_type_p (Lisp_Object type) { - if (decode_specifier_type (type, ERROR_ME_NOT)) - return 1; - return 0; + return decode_specifier_type (type, ERROR_ME_NOT) != 0; } DEFUN ("valid-specifier-type-p", Fvalid_specifier_type_p, 1, 1, 0, /* @@ -373,10 +365,7 @@ */ (specifier_type)) { - if (valid_specifier_type_p (specifier_type)) - return Qt; - else - return Qnil; + return valid_specifier_type_p (specifier_type) ? Qt : Qnil; } DEFUN ("specifier-type-list", Fspecifier_type_list, 0, 0, 0, /* @@ -402,7 +391,7 @@ static Lisp_Object make_specifier (struct specifier_methods *spec_meths) { - Lisp_Object specifier = Qnil; + Lisp_Object specifier; struct gcpro gcpro1; struct Lisp_Specifier *sp = (struct Lisp_Specifier *) alloc_lcrecord (sizeof (struct Lisp_Specifier) + @@ -428,7 +417,7 @@ } DEFUN ("make-specifier", Fmake_specifier, 1, 1, 0, /* -Create a new specifier. +Return a new specifier object of type TYPE. A specifier is an object that can be used to keep track of a property whose value can be per-buffer, per-window, per-frame, or per-device, @@ -460,7 +449,7 @@ } DEFUN ("specifierp", Fspecifierp, 1, 1, 0, /* -Return non-nil if OBJECT is a specifier. +Return t if OBJECT is a specifier. A specifier is an object that can be used to keep track of a property whose value can be per-buffer, per-window, per-frame, or per-device, @@ -469,9 +458,7 @@ */ (object)) { - if (!SPECIFIERP (object)) - return Qnil; - return Qt; + return SPECIFIERP (object) ? Qt : Qnil; } DEFUN ("specifier-type", Fspecifier_type, 1, 1, 0, /* @@ -489,59 +476,52 @@ /************************************************************************/ DEFUN ("valid-specifier-locale-p", Fvalid_specifier_locale_p, 1, 1, 0, /* -Return non-nil if LOCALE is a valid specifier locale. -Valid locales are a device, a frame, a window, a buffer, and 'global. -(nil is not valid.) +Return t if LOCALE is a valid specifier locale. +Valid locales are devices, frames, windows, buffers, and 'global. +\(nil is not valid.) */ (locale)) { /* This cannot GC. */ - if ((DEVICEP (locale) && DEVICE_LIVE_P (XDEVICE (locale))) || - (FRAMEP (locale) && FRAME_LIVE_P (XFRAME (locale))) || - (BUFFERP (locale) && BUFFER_LIVE_P (XBUFFER (locale))) || - /* dead windows are allowed because they may become live - windows again when a window configuration is restored */ - WINDOWP (locale) || - EQ (locale, Qglobal)) - return Qt; - else - return Qnil; + return ((DEVICEP (locale) && DEVICE_LIVE_P (XDEVICE (locale))) || + (FRAMEP (locale) && FRAME_LIVE_P (XFRAME (locale))) || + (BUFFERP (locale) && BUFFER_LIVE_P (XBUFFER (locale))) || + /* dead windows are allowed because they may become live + windows again when a window configuration is restored */ + WINDOWP (locale) || + EQ (locale, Qglobal)) + ? Qt : Qnil; } DEFUN ("valid-specifier-domain-p", Fvalid_specifier_domain_p, 1, 1, 0, /* -Return non-nil if DOMAIN is a valid specifier domain. +Return t if DOMAIN is a valid specifier domain. A domain is used to instance a specifier (i.e. determine the specifier's -value in that domain). Valid domains are a window, frame, or device. -(nil is not valid.) +value in that domain). Valid domains are windows, frames, and devices. +\(nil is not valid.) */ (domain)) { /* This cannot GC. */ - if ((DEVICEP (domain) && DEVICE_LIVE_P (XDEVICE (domain))) || - (FRAMEP (domain) && FRAME_LIVE_P (XFRAME (domain))) || - (WINDOWP (domain) && WINDOW_LIVE_P (XWINDOW (domain)))) - return Qt; - else - return Qnil; + return ((DEVICEP (domain) && DEVICE_LIVE_P (XDEVICE (domain))) || + (FRAMEP (domain) && FRAME_LIVE_P (XFRAME (domain))) || + (WINDOWP (domain) && WINDOW_LIVE_P (XWINDOW (domain)))) + ? Qt : Qnil; } DEFUN ("valid-specifier-locale-type-p", Fvalid_specifier_locale_type_p, 1, 1, 0, /* Given a specifier LOCALE-TYPE, return non-nil if it is valid. Valid locale types are 'global, 'device, 'frame, 'window, and 'buffer. -(Note, however, that in functions that accept either a locale or a locale +\(Note, however, that in functions that accept either a locale or a locale type, 'global is considered an individual locale.) */ (locale_type)) { /* This cannot GC. */ - if (EQ (locale_type, Qglobal) || - EQ (locale_type, Qdevice) || - EQ (locale_type, Qframe) || - EQ (locale_type, Qwindow) || - EQ (locale_type, Qbuffer)) - return Qt; - else - return Qnil; + return (EQ (locale_type, Qglobal) || + EQ (locale_type, Qdevice) || + EQ (locale_type, Qframe) || + EQ (locale_type, Qwindow) || + EQ (locale_type, Qbuffer)) ? Qt : Qnil; } static void @@ -555,7 +535,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)) @@ -563,19 +544,15 @@ /* This cannot GC. */ if (NILP (Fvalid_specifier_locale_p (locale))) signal_simple_error ("Invalid specifier locale", locale); - if (DEVICEP (locale)) - return Qdevice; - if (FRAMEP (locale)) - return Qframe; - if (WINDOWP (locale)) - return Qwindow; - if (BUFFERP (locale)) - return Qbuffer; + if (DEVICEP (locale)) return Qdevice; + if (FRAMEP (locale)) return Qframe; + if (WINDOWP (locale)) return Qwindow; + if (BUFFERP (locale)) return Qbuffer; assert (EQ (locale, Qglobal)); return Qglobal; } -Lisp_Object +static Lisp_Object decode_locale (Lisp_Object locale) { /* This cannot GC. */ @@ -634,7 +611,7 @@ signal_simple_error ("Invalid specifier domain", domain); } -Lisp_Object +static Lisp_Object decode_domain (Lisp_Object domain) { if (NILP (domain)) @@ -654,11 +631,9 @@ */ (tag)) { - if (valid_console_type_p (tag) || - valid_device_class_p (tag) || - !NILP (assq_no_quit (tag, Vuser_defined_tags))) - return Qt; - return Qnil; + return (valid_console_type_p (tag) || + valid_device_class_p (tag) || + !NILP (assq_no_quit (tag, Vuser_defined_tags))) ? Qt : Qnil; } DEFUN ("valid-specifier-tag-set-p", Fvalid_specifier_tag_set_p, 1, 1, 0, /* @@ -671,9 +646,9 @@ A specifier tag set consists of a list of zero of more specifier tags, each of which is a symbol that is recognized by XEmacs as a tag. -(The valid device types and device classes are always tags, as are +\(The valid device types and device classes are always tags, as are any tags defined by `define-specifier-tag'.) It is called a "tag set" -(as opposed to a list) because the order of the tags or the number of +\(as opposed to a list) because the order of the tags or the number of times a particular tag occurs does not matter. Each tag has a predicate associated with it, which specifies whether @@ -821,7 +796,7 @@ DEFUN ("define-specifier-tag", Fdefine_specifier_tag, 1, 2, 0, /* Define a new specifier tag. If PREDICATE is specified, it should be a function of one argument -(a device) that specifies whether the tag matches that particular +\(a device) that specifies whether the tag matches that particular device. If PREDICATE is omitted, the tag matches all devices. You can redefine an existing user-defined specifier tag. However, @@ -893,7 +868,7 @@ setup_device_initial_specifier_tags (struct device *d) { Lisp_Object rest, rest2; - Lisp_Object device = Qnil; + Lisp_Object device; XSETDEVICE (device, d); @@ -914,7 +889,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. */ @@ -934,7 +910,7 @@ list = Fnreverse (list); list = Fcons (DEVICE_CLASS (d), list); - list = Fcons (DEVICE_TYPE (d), list); + list = Fcons (DEVICE_TYPE (d), list); RETURN_UNGCPRO (list); } @@ -1092,21 +1068,28 @@ LIST_LOOP (rest, inst_list) { - if (!CONSP (rest) || !CONSP (XCAR (rest))) + Lisp_Object inst_pair, tag_set; + + if (!CONSP (rest)) { maybe_signal_simple_error ("Invalid instantiator list", inst_list, Qspecifier, errb); return Qnil; } - if (NILP (Fvalid_specifier_tag_set_p (XCAR (XCAR (rest))))) + if (!CONSP (inst_pair = XCAR (rest))) { - maybe_signal_simple_error ("Invalid specifier tag", - XCAR (XCAR (rest)), Qspecifier, errb); + maybe_signal_simple_error ("Invalid instantiator pair", inst_pair, + Qspecifier, errb); return Qnil; } - - if (NILP (check_valid_instantiator (XCDR (XCAR (rest)), meths, - errb))) + if (NILP (Fvalid_specifier_tag_set_p (tag_set = XCAR (inst_pair)))) + { + maybe_signal_simple_error ("Invalid specifier tag", tag_set, + Qspecifier, errb); + return Qnil; + } + + if (NILP (check_valid_instantiator (XCDR (inst_pair), meths, errb))) return Qnil; } @@ -1141,21 +1124,21 @@ LIST_LOOP (rest, spec_list) { - if (!CONSP (rest) || !CONSP (XCAR (rest))) + Lisp_Object spec, locale; + if (!CONSP (rest) || !CONSP (spec = XCAR (rest))) { maybe_signal_simple_error ("Invalid specification list", spec_list, Qspecifier, errb); return Qnil; } - if (NILP (Fvalid_specifier_locale_p (XCAR (XCAR (rest))))) + if (NILP (Fvalid_specifier_locale_p (locale = XCAR (spec)))) { - maybe_signal_simple_error ("Invalid specifier locale", - XCAR (XCAR (rest)), + maybe_signal_simple_error ("Invalid specifier locale", locale, Qspecifier, errb); return Qnil; } - if (NILP (check_valid_inst_list (XCDR (XCAR (rest)), meths, errb))) + if (NILP (check_valid_inst_list (XCDR (spec), meths, errb))) return Qnil; } @@ -1459,36 +1442,38 @@ Lisp_Object new_list, enum spec_add_meth add_meth) { - if (add_meth == SPEC_REMOVE_TAG_SET_PREPEND || - add_meth == SPEC_REMOVE_TAG_SET_APPEND) + switch (add_meth) { - Lisp_Object rest; - - LIST_LOOP (rest, new_list) - { - Lisp_Object canontag = canonicalize_tag_set (XCAR (XCAR (rest))); - struct gcpro gcpro1; - - GCPRO1 (canontag); - /* pull out all elements from the existing list with the - same tag as any tags in NEW_LIST. */ - *inst_list = remassoc_no_quit (canontag, *inst_list); - UNGCPRO; - } - if (add_meth == SPEC_REMOVE_TAG_SET_PREPEND) - return SPEC_PREPEND; - else - return SPEC_APPEND; - } - else if (add_meth == SPEC_REMOVE_LOCALE) - { + case SPEC_REMOVE_TAG_SET_APPEND: + add_meth = SPEC_APPEND; + goto remove_tag_set; + case SPEC_REMOVE_TAG_SET_PREPEND: + add_meth = SPEC_PREPEND; + remove_tag_set: + { + Lisp_Object rest; + + LIST_LOOP (rest, new_list) + { + Lisp_Object canontag = canonicalize_tag_set (XCAR (XCAR (rest))); + struct gcpro gcpro1; + + GCPRO1 (canontag); + /* pull out all elements from the existing list with the + same tag as any tags in NEW_LIST. */ + *inst_list = remassoc_no_quit (canontag, *inst_list); + UNGCPRO; + } + } + return add_meth; + case SPEC_REMOVE_LOCALE: *inst_list = Qnil; return SPEC_PREPEND; + case SPEC_APPEND: + return add_meth; + default: + return SPEC_PREPEND; } - if (add_meth == SPEC_APPEND) - return add_meth; - - return SPEC_PREPEND; } /* Given a LOCALE and INST_LIST that is going to be added to SPECIFIER, @@ -1502,6 +1487,7 @@ { /* The return value of this function must be GCPRO'd. */ Lisp_Object rest, list_to_build_up = Qnil; + struct Lisp_Specifier *sp = XSPECIFIER (specifier); struct gcpro gcpro1; GCPRO1 (list_to_build_up); @@ -1514,9 +1500,10 @@ NGCPRO2 (instantiator, sub_inst_list); /* call the will-add method; it may GC */ - sub_inst_list = SPECMETH_OR_GIVEN (XSPECIFIER (specifier), going_to_add, - (specifier, locale, tag_set, - instantiator), Qt); + sub_inst_list = HAS_SPECMETH_P (sp, going_to_add) ? + SPECMETH (sp, going_to_add, + (specifier, locale, tag_set, instantiator)) : + Qt; if (EQ (sub_inst_list, Qt)) /* no change here. */ sub_inst_list = list1 (Fcons (canonicalize_tag_set (tag_set), @@ -1551,13 +1538,11 @@ Lisp_Object inst_list, enum spec_add_meth add_meth) { struct Lisp_Specifier *sp = XSPECIFIER (specifier); - enum spec_locale_type type; - Lisp_Object *orig_inst_list; + enum spec_locale_type type = locale_type_from_locale (locale); + Lisp_Object *orig_inst_list, tem; Lisp_Object list_to_build_up = Qnil; struct gcpro gcpro1; - type = locale_type_from_locale (locale); - GCPRO1 (list_to_build_up); list_to_build_up = build_up_processed_list (specifier, locale, inst_list); /* Now handle REMOVE_LOCALE_TYPE and REMOVE_ALL. These are the @@ -1568,7 +1553,7 @@ { specifier_remove_locale_type (specifier, LOCALE_BUFFER, Qnil, 0); specifier_remove_locale_type (specifier, LOCALE_WINDOW, Qnil, 0); - specifier_remove_locale_type (specifier, LOCALE_FRAME, Qnil, 0); + specifier_remove_locale_type (specifier, LOCALE_FRAME, Qnil, 0); specifier_remove_locale_type (specifier, LOCALE_DEVICE, Qnil, 0); specifier_remove_spec (specifier, Qglobal, LOCALE_GLOBAL, Qnil, 0); } @@ -1580,16 +1565,14 @@ add_meth); if (add_meth == SPEC_PREPEND) - { - *orig_inst_list = nconc2 (list_to_build_up, *orig_inst_list); - } + tem = nconc2 (list_to_build_up, *orig_inst_list); else if (add_meth == SPEC_APPEND) - { - *orig_inst_list = nconc2 (*orig_inst_list, list_to_build_up); - } + tem = nconc2 (*orig_inst_list, list_to_build_up); else abort (); + *orig_inst_list = tem; + UNGCPRO; /* call the after-change method */ @@ -1825,11 +1808,11 @@ LIST_LOOP (rest, spec_list) { /* Placating the GCC god. */ - Lisp_Object crock1 = specifier; - Lisp_Object crock2 = XCAR (XCAR (rest)); - Lisp_Object crock3 = XCDR (XCAR (rest)); - - specifier_add_spec (crock1, crock2, crock3, add_meth); + Lisp_Object specification = XCAR (rest); + Lisp_Object locale = XCAR (specification); + Lisp_Object inst_list = XCDR (specification); + + specifier_add_spec (specifier, locale, inst_list, add_meth); } recompute_cached_specifier_everywhere (specifier); return Qnil; @@ -1909,7 +1892,7 @@ Only instantiators where TAG-SET (a list of zero or more tags) is a subset of (or possibly equal to) the instantiator's tag set are returned. -(The default value of nil is a subset of all tag sets, so in this case +\(The default value of nil is a subset of all tag sets, so in this case no instantiators will be screened out.) If EXACT-P is non-nil, however, TAG-SET must be equal to an instantiator's tag set for the instantiator to be returned. @@ -2274,7 +2257,7 @@ val = call_with_suspended_errors ((lisp_fn_t) RAW_SPECMETH (sp, instantiate), Qunbound, Qspecifier, errb, 5, specifier, - matchspec, domain, XCDR (tagged_inst), depth); + matchspec, domain, val, depth); if (!UNBOUNDP (val)) { @@ -2549,7 +2532,7 @@ 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), +\(as if INST-LIST existed in a specification in SPECIFIER), matching the specifications against MATCHSPEC. This function is analogous to `specifier-instance-from-inst-list' @@ -2616,7 +2599,7 @@ recompute_one_cached_specifier_in_window (Lisp_Object specifier, struct window *w) { - Lisp_Object window = Qnil; + Lisp_Object window; Lisp_Object newval, *location; XSETWINDOW (window, w); @@ -2642,7 +2625,7 @@ recompute_one_cached_specifier_in_frame (Lisp_Object specifier, struct frame *f) { - Lisp_Object frame = Qnil; + Lisp_Object frame; Lisp_Object newval, *location; XSETFRAME (frame, f);