summaryrefslogtreecommitdiff
path: root/src/data.c
diff options
context:
space:
mode:
authorDmitry Antipov <dmantipov@yandex.ru>2014-07-16 12:45:22 +0400
committerDmitry Antipov <dmantipov@yandex.ru>2014-07-16 12:45:22 +0400
commite0b07ec3416d1ee7c77234e9dd0a7408b50da83c (patch)
tree430fc691f2cc593268fd1ada8defcec5b9c78ef4 /src/data.c
parent74660d84d923fd8252b166770ca2403f6025a7ac (diff)
downloademacs-e0b07ec3416d1ee7c77234e9dd0a7408b50da83c.tar.gz
More precise control over values of some buffer-local variables.
* keyboard.c (Qvertical_scroll_bar): * frame.c (Qleft, Qright): Move to ... * buffer.c (Qleft, Qright, Qvertical_scroll_bar): ... here. * buffer.c (Qchoice, Qrange, Qoverwrite_mode, Qfraction): New symbols. (syms_of_buffer): DEFSYM all of the above, attach special properties. Use special symbols to DEFVAR_PER_BUFFER overwrite-mode, vertical-scroll-bar, scroll-up-aggressively and scroll-down-aggressively. * buffer.h (Qchoice, Qrange, Qleft, Qright, Qvertical_scroll_bar): Add declarations. * nsfns.m, frame.h (Qleft, Qright): * nsterm.m (Qleft): Remove declarations. * gtkutil.c (toplevel): Include buffer.h. * data.c (wrong_choice, wrong_range): New functions. (store_symval_forwarding): Handle special properties of buffer-local variables and use functions from the above to signal error, if any.
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c71
1 files changed, 68 insertions, 3 deletions
diff --git a/src/data.c b/src/data.c
index 2de1c19452c..790d0fee981 100644
--- a/src/data.c
+++ b/src/data.c
@@ -971,6 +971,48 @@ do_symval_forwarding (register union Lisp_Fwd *valcontents)
}
}
+/* Used to signal a user-friendly error when symbol WRONG is
+ not a member of CHOICE, which should be a list of symbols. */
+
+static void
+wrong_choice (Lisp_Object choice, Lisp_Object wrong)
+{
+ ptrdiff_t i = 0, len = XINT (Flength (choice));
+ Lisp_Object obj, *args;
+
+ USE_SAFE_ALLOCA;
+ SAFE_ALLOCA_LISP (args, len * 2 + 1);
+
+ args[i++] = build_string ("One of ");
+
+ for (obj = choice; !NILP (obj); obj = XCDR (obj))
+ {
+ args[i++] = SYMBOL_NAME (XCAR (obj));
+ args[i++] = build_string (NILP (XCDR (obj)) ? " should be specified"
+ : (NILP (XCDR (XCDR (obj))) ? " or " : ", "));
+ }
+
+ obj = Fconcat (i, args);
+ SAFE_FREE ();
+ xsignal2 (Qerror, obj, wrong);
+}
+
+/* Used to signal a user-friendly error if WRONG is not a number or
+ integer/floating-point number outsize of inclusive MIN..MAX range. */
+
+static void
+wrong_range (Lisp_Object min, Lisp_Object max, Lisp_Object wrong)
+{
+ Lisp_Object args[4];
+
+ args[0] = build_string ("Value should be from ");
+ args[1] = Fnumber_to_string (min);
+ args[2] = build_string (" to ");
+ args[3] = Fnumber_to_string (max);
+
+ xsignal2 (Qerror, Fconcat (4, args), wrong);
+}
+
/* Store NEWVAL into SYMBOL, where VALCONTENTS is found in the value cell
of SYMBOL. If SYMBOL is buffer-local, VALCONTENTS should be the
buffer-independent contents of the value cell: forwarded just one
@@ -1027,10 +1069,33 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva
int offset = XBUFFER_OBJFWD (valcontents)->offset;
Lisp_Object predicate = XBUFFER_OBJFWD (valcontents)->predicate;
- if (!NILP (predicate) && !NILP (newval)
- && NILP (call1 (predicate, newval)))
- wrong_type_argument (predicate, newval);
+ if (!NILP (newval))
+ {
+ if (SYMBOLP (predicate))
+ {
+ Lisp_Object prop;
+
+ if ((prop = Fget (predicate, Qchoice), !NILP (prop)))
+ {
+ if (NILP (Fmemq (newval, prop)))
+ wrong_choice (prop, newval);
+ }
+ else if ((prop = Fget (predicate, Qrange), !NILP (prop)))
+ {
+ Lisp_Object min = XCAR (prop), max = XCDR (prop);
+ if (!NUMBERP (newval)
+ || !NILP (arithcompare (newval, min, ARITH_LESS))
+ || !NILP (arithcompare (newval, max, ARITH_GRTR)))
+ wrong_range (min, max, newval);
+ }
+ else if (FUNCTIONP (predicate))
+ {
+ if (NILP (call1 (predicate, newval)))
+ wrong_type_argument (predicate, newval);
+ }
+ }
+ }
if (buf == NULL)
buf = current_buffer;
set_per_buffer_value (buf, offset, newval);