]> code.delx.au - gnu-emacs/blobdiff - src/data.c
(Voverflow_newline_into_fringe, syms_of_xdisp)
[gnu-emacs] / src / data.c
index 5ccc3194b2987957d079f759b5684efbefff7f0b..c4e3937f3fa26eb59af235ac6f9881e5c9a227cb 100644 (file)
@@ -1,5 +1,5 @@
 /* Primitive operations on Lisp data types for GNU Emacs Lisp interpreter.
-   Copyright (C) 1985,86,88,93,94,95,97,98,99, 2000, 2001
+   Copyright (C) 1985,86,88,93,94,95,97,98,99, 2000, 2001, 2003
    Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -71,6 +71,7 @@ Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
 Lisp_Object Qend_of_file, Qarith_error, Qmark_inactive;
 Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
 Lisp_Object Qtext_read_only;
+
 Lisp_Object Qintegerp, Qnatnump, Qwholenump, Qsymbolp, Qlistp, Qconsp;
 Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp;
 Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp;
@@ -87,7 +88,8 @@ Lisp_Object Qoverflow_error, Qunderflow_error;
 Lisp_Object Qfloatp;
 Lisp_Object Qnumberp, Qnumber_or_marker_p;
 
-static Lisp_Object Qinteger, Qsymbol, Qstring, Qcons, Qmarker, Qoverlay;
+Lisp_Object Qinteger;
+static Lisp_Object Qsymbol, Qstring, Qcons, Qmarker, Qoverlay;
 static Lisp_Object Qfloat, Qwindow_configuration, Qwindow;
 Lisp_Object Qprocess;
 static Lisp_Object Qcompiled_function, Qbuffer, Qframe, Qvector;
@@ -728,7 +730,7 @@ determined by DEFINITION.  */)
 }
 
 DEFUN ("setplist", Fsetplist, Ssetplist, 2, 2, 0,
-       doc: /* Set SYMBOL's property list to NEWVAL, and return NEWVAL.  */)
+       doc: /* Set SYMBOL's property list to NEWPLIST, and return NEWPLIST.  */)
      (symbol, newplist)
      register Lisp_Object symbol, newplist;
 {
@@ -871,6 +873,8 @@ store_symval_forwarding (symbol, valcontents, newval, buf)
      register Lisp_Object valcontents, newval;
      struct buffer *buf;
 {
+  int offset;
+
   switch (SWITCH_ENUM_CAST (XTYPE (valcontents)))
     {
     case Lisp_Misc:
@@ -890,6 +894,36 @@ store_symval_forwarding (symbol, valcontents, newval, buf)
 
        case Lisp_Misc_Objfwd:
          *XOBJFWD (valcontents)->objvar = newval;
+
+         /* If this variable is a default for something stored
+            in the buffer itself, such as default-fill-column,
+            find the buffers that don't have local values for it
+            and update them.  */
+         if (XOBJFWD (valcontents)->objvar > (Lisp_Object *) &buffer_defaults
+             && XOBJFWD (valcontents)->objvar < (Lisp_Object *) (&buffer_defaults + 1))
+           {
+             int offset = ((char *) XOBJFWD (valcontents)->objvar
+                           - (char *) &buffer_defaults);
+             int idx = PER_BUFFER_IDX (offset);
+
+             Lisp_Object tail, buf;
+
+             if (idx <= 0)
+               break;
+
+             for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
+               {
+                 Lisp_Object buf;
+                 struct buffer *b;
+
+                 buf = Fcdr (XCAR (tail));
+                 if (!BUFFERP (buf)) continue;
+                 b = XBUFFER (buf);
+
+                 if (! PER_BUFFER_VALUE_P (b, idx))
+                   PER_BUFFER_VALUE (b, offset) = newval;
+               }
+           }
          break;
 
        case Lisp_Misc_Buffer_Objfwd:
@@ -898,9 +932,6 @@ store_symval_forwarding (symbol, valcontents, newval, buf)
            Lisp_Object type;
 
            type = PER_BUFFER_TYPE (offset);
-           if (XINT (type) == -1)
-             error ("Variable %s is read-only", SDATA (SYMBOL_NAME (symbol)));
-
            if (! NILP (type) && ! NILP (newval)
                && XTYPE (newval) != XINT (type))
              buffer_slot_type_mismatch (offset);
@@ -1095,7 +1126,7 @@ static int
 let_shadows_buffer_binding_p (symbol)
      Lisp_Object symbol;
 {
-  struct specbinding *p;
+  volatile struct specbinding *p;
 
   for (p = specpdl_ptr - 1; p >= specpdl; p--)
     if (p->func == NULL
@@ -1452,6 +1483,7 @@ The function `default-value' gets the default value and `set-default' sets it.
   register Lisp_Object tem, valcontents, newval;
 
   CHECK_SYMBOL (variable);
+  variable = indirect_variable (variable);
 
   valcontents = SYMBOL_VALUE (variable);
   if (EQ (variable, Qnil) || EQ (variable, Qt) || KBOARD_OBJFWDP (valcontents))
@@ -1505,6 +1537,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument.  */)
   register Lisp_Object tem, valcontents;
 
   CHECK_SYMBOL (variable);
+  variable = indirect_variable (variable);
 
   valcontents = SYMBOL_VALUE (variable);
   if (EQ (variable, Qnil) || EQ (variable, Qt) || KBOARD_OBJFWDP (valcontents))
@@ -1584,6 +1617,7 @@ From now on the default value will apply in this buffer.  Return VARIABLE.  */)
   register Lisp_Object tem, valcontents;
 
   CHECK_SYMBOL (variable);
+  variable = indirect_variable (variable);
 
   valcontents = SYMBOL_VALUE (variable);
 
@@ -1616,10 +1650,11 @@ From now on the default value will apply in this buffer.  Return VARIABLE.  */)
      loaded, recompute its value.  We have to do it now, or else
      forwarded objects won't work right.  */
   {
-    Lisp_Object *pvalbuf;
+    Lisp_Object *pvalbuf, buf;
     valcontents = SYMBOL_VALUE (variable);
     pvalbuf = &XBUFFER_LOCAL_VALUE (valcontents)->buffer;
-    if (current_buffer == XBUFFER (*pvalbuf))
+    XSETBUFFER (buf, current_buffer);
+    if (EQ (buf, *pvalbuf))
       {
        *pvalbuf = Qnil;
        XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0;
@@ -1647,6 +1682,7 @@ See `modify-frame-parameters' for how to set frame parameters.  */)
   register Lisp_Object tem, valcontents, newval;
 
   CHECK_SYMBOL (variable);
+  variable = indirect_variable (variable);
 
   valcontents = SYMBOL_VALUE (variable);
   if (EQ (variable, Qnil) || EQ (variable, Qt) || KBOARD_OBJFWDP (valcontents)
@@ -1696,6 +1732,7 @@ BUFFER defaults to the current buffer.  */)
     }
 
   CHECK_SYMBOL (variable);
+  variable = indirect_variable (variable);
 
   valcontents = SYMBOL_VALUE (variable);
   if (BUFFER_LOCAL_VALUEP (valcontents)
@@ -1703,7 +1740,6 @@ BUFFER defaults to the current buffer.  */)
     {
       Lisp_Object tail, elt;
 
-      variable = indirect_variable (variable);
       for (tail = buf->local_var_alist; CONSP (tail); tail = XCDR (tail))
        {
          elt = XCAR (tail);
@@ -1740,6 +1776,7 @@ BUFFER defaults to the current buffer.  */)
     }
 
   CHECK_SYMBOL (variable);
+  variable = indirect_variable (variable);
 
   valcontents = SYMBOL_VALUE (variable);
 
@@ -1761,6 +1798,41 @@ BUFFER defaults to the current buffer.  */)
     }
   return Qnil;
 }
+
+DEFUN ("variable-binding-locus", Fvariable_binding_locus, Svariable_binding_locus,
+       1, 1, 0,
+       doc: /* Return a value indicating where VARIABLE's current binding comes from.
+If the current binding is buffer-local, the value is the current buffer.
+If the current binding is frame-local, the value is the selected frame.
+If the current binding is global (the default), the value is nil.  */)
+     (variable)
+     register Lisp_Object variable;
+{
+  Lisp_Object valcontents;
+
+  CHECK_SYMBOL (variable);
+  variable = indirect_variable (variable);
+
+  /* Make sure the current binding is actually swapped in.  */
+  find_symbol_value (variable);
+
+  valcontents = XSYMBOL (variable)->value;
+
+  if (BUFFER_LOCAL_VALUEP (valcontents)
+      || SOME_BUFFER_LOCAL_VALUEP (valcontents)
+      || BUFFER_OBJFWDP (valcontents))
+    {
+      /* For a local variable, record both the symbol and which
+        buffer's or frame's value we are saving.  */
+      if (!NILP (Flocal_variable_p (variable, Qnil)))
+       return Fcurrent_buffer ();
+      else if (!BUFFER_OBJFWDP (valcontents)
+              && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame)
+       return XBUFFER_LOCAL_VALUE (valcontents)->frame;
+    }
+
+  return Qnil;
+}
 \f
 /* Find the function at the end of a chain of symbol function indirections.  */
 
@@ -2031,13 +2103,15 @@ bool-vector.  IDX starts at 0.  */)
     }
   else if (STRING_MULTIBYTE (array))
     {
-      int idxval_byte, prev_bytes, new_bytes;
+      int idxval_byte, prev_bytes, new_bytes, nbytes;
       unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1;
 
       if (idxval < 0 || idxval >= SCHARS (array))
        args_out_of_range (array, idx);
       CHECK_NUMBER (newelt);
 
+      nbytes = SBYTES (array);
+
       idxval_byte = string_char_to_byte (array, idxval);
       p1 = SDATA (array) + idxval_byte;
       PARSE_MULTIBYTE_SEQ (p1, nbytes - idxval_byte, prev_bytes);
@@ -2046,7 +2120,6 @@ bool-vector.  IDX starts at 0.  */)
        {
          /* We must relocate the string data.  */
          int nchars = SCHARS (array);
-         int nbytes = SBYTES (array);
          unsigned char *str;
 
          str = (nbytes <= MAX_ALLOCA
@@ -2245,7 +2318,7 @@ Lisp_Object
 long_to_cons (i)
      unsigned long i;
 {
-  unsigned int top = i >> 16;
+  unsigned long top = i >> 16;
   unsigned int bot = i & 0xFFFF;
   if (top == 0)
     return make_number (bot);
@@ -2318,7 +2391,7 @@ digit_to_number (character, base)
 }
 
 DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0,
-       doc: /* Return a number obtained by parsing STRING as a decimal number.
+       doc: /* Parse STRING as a decimal number and return the number.
 This parses both integers and floating point numbers.
 It ignores leading spaces and tabs.
 
@@ -2561,7 +2634,7 @@ usage: (+ &rest NUMBERS-OR-MARKERS)  */)
 }
 
 DEFUN ("-", Fminus, Sminus, 0, MANY, 0,
-       doc: /* Negate number or subtract numbers or markers, returns the result.
+       doc: /* Negate number or subtract numbers or markers and return the result.
 With one arg, negates it.  With more than one arg,
 subtracts all but the first from the first.
 usage: (- &optional NUMBER-OR-MARKER &rest MORE-NUMBERS-OR-MARKERS)  */)
@@ -3180,6 +3253,7 @@ syms_of_data ()
   defsubr (&Smake_variable_frame_local);
   defsubr (&Slocal_variable_p);
   defsubr (&Slocal_variable_if_set_p);
+  defsubr (&Svariable_binding_locus);
   defsubr (&Saref);
   defsubr (&Saset);
   defsubr (&Snumber_to_string);
@@ -3259,3 +3333,6 @@ init_data ()
   signal (SIGEMT, arith_error);
 #endif /* uts */
 }
+
+/* arch-tag: 25879798-b84d-479a-9c89-7d148e2109f7
+   (do not change this comment) */