]> code.delx.au - gnu-emacs/blobdiff - src/fns.c
(Frequire): Pass t for the MUST-SUFFIX arg to Fload.
[gnu-emacs] / src / fns.c
index a7bcc28c3dd14bfe24f72b7041d997fb22dbd0a0..8387f8700361f660c10deccee93a02fbaab2abf0 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -40,6 +40,10 @@ Boston, MA 02111-1307, USA.  */
 #define NULL (void *)0
 #endif
 
+/* Nonzero enables use of dialog boxes for questions
+   asked by mouse commands.  */
+int use_dialog_box;
+
 extern Lisp_Object Flookup_key ();
 
 extern int minibuffer_auto_raise;
@@ -406,7 +410,23 @@ concat (nargs, args, target_type, last_special)
     {
       this = args[argnum];
       len = Flength (this);
-      leni += XFASTINT (len);
+      if (VECTORP (this) && target_type == Lisp_String)
+       {
+         /* We must pay attention to a multibyte character which
+             takes more than one byte in string.  */
+         int i;
+         Lisp_Object ch;
+
+         for (i = 0; i < XFASTINT (len); i++)
+           {
+             ch = XVECTOR (this)->contents[i];
+             if (! INTEGERP (ch))
+               wrong_type_argument (Qintegerp, ch);
+             leni += Fchar_bytes (ch);
+           }
+       }
+      else
+       leni += XFASTINT (len);
     }
 
   XSETFASTINT (len, leni);
@@ -454,7 +474,7 @@ concat (nargs, args, target_type, last_special)
              `this' is exhausted. */
          if (NILP (this)) break;
          if (CONSP (this))
-           elt = Fcar (this), this = Fcdr (this);
+           elt = XCONS (this)->car, this = XCONS (this)->cdr;
          else
            {
              if (thisindex >= thisleni) break;
@@ -490,14 +510,19 @@ concat (nargs, args, target_type, last_special)
              while (!INTEGERP (elt))
                elt = wrong_type_argument (Qintegerp, elt);
              {
+               int c = XINT (elt);
+               unsigned char work[4], *str;
+               int i = CHAR_STRING (c, work, str);
+
 #ifdef MASSC_REGISTER_BUG
                /* Even removing all "register"s doesn't disable this bug!
                   Nothing simpler than this seems to work. */
-               unsigned char *p = & XSTRING (val)->data[toindex++];
-               *p = XINT (elt);
+               unsigned char *p = & XSTRING (val)->data[toindex];
+               bcopy (str, p, i);
 #else
-               XSTRING (val)->data[toindex++] = XINT (elt);
+               bcopy (str, & XSTRING (val)->data[toindex], i);
 #endif
+               toindex += i;
              }
            }
        }
@@ -559,7 +584,7 @@ This function allows vectors as well as strings.")
     size = XVECTOR (string)->size;
 
   if (NILP (to))
-    to = size;
+    XSETINT (to, size);
   else
     CHECK_NUMBER (to, 2);
 
@@ -636,7 +661,7 @@ The value is actually the tail of LIST whose car is ELT.")
      Lisp_Object list;
 {
   register Lisp_Object tail;
-  for (tail = list; !NILP (tail); tail = Fcdr (tail))
+  for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
     {
       register Lisp_Object tem;
       tem = Fcar (tail);
@@ -655,7 +680,7 @@ The value is actually the tail of LIST whose car is ELT.")
      Lisp_Object list;
 {
   register Lisp_Object tail;
-  for (tail = list; !NILP (tail); tail = Fcdr (tail))
+  for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
     {
       register Lisp_Object tem;
       tem = Fcar (tail);
@@ -674,12 +699,12 @@ Elements of LIST that are not conses are ignored.")
      Lisp_Object list;
 {
   register Lisp_Object tail;
-  for (tail = list; !NILP (tail); tail = Fcdr (tail))
+  for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
     {
       register Lisp_Object elt, tem;
       elt = Fcar (tail);
       if (!CONSP (elt)) continue;
-      tem = Fcar (elt);
+      tem = XCONS (elt)->car;
       if (EQ (key, tem)) return elt;
       QUIT;
     }
@@ -695,12 +720,12 @@ assq_no_quit (key, list)
      Lisp_Object list;
 {
   register Lisp_Object tail;
-  for (tail = list; CONSP (tail); tail = Fcdr (tail))
+  for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
     {
       register Lisp_Object elt, tem;
       elt = Fcar (tail);
       if (!CONSP (elt)) continue;
-      tem = Fcar (elt);
+      tem = XCONS (elt)->car;
       if (EQ (key, tem)) return elt;
     }
   return Qnil;
@@ -714,12 +739,12 @@ The value is actually the element of LIST whose car equals KEY.")
      Lisp_Object list;
 {
   register Lisp_Object tail;
-  for (tail = list; !NILP (tail); tail = Fcdr (tail))
+  for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
     {
       register Lisp_Object elt, tem;
       elt = Fcar (tail);
       if (!CONSP (elt)) continue;
-      tem = Fequal (Fcar (elt), key);
+      tem = Fequal (XCONS (elt)->car, key);
       if (!NILP (tem)) return elt;
       QUIT;
     }
@@ -734,12 +759,12 @@ The value is actually the element of LIST whose cdr is ELT.")
      Lisp_Object list;
 {
   register Lisp_Object tail;
-  for (tail = list; !NILP (tail); tail = Fcdr (tail))
+  for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
     {
       register Lisp_Object elt, tem;
       elt = Fcar (tail);
       if (!CONSP (elt)) continue;
-      tem = Fcdr (elt);
+      tem = XCONS (elt)->cdr;
       if (EQ (key, tem)) return elt;
       QUIT;
     }
@@ -754,12 +779,12 @@ The value is actually the element of LIST whose cdr equals KEY.")
      Lisp_Object list;
 {
   register Lisp_Object tail;
-  for (tail = list; !NILP (tail); tail = Fcdr (tail))
+  for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
     {
       register Lisp_Object elt, tem;
       elt = Fcar (tail);
       if (!CONSP (elt)) continue;
-      tem = Fequal (Fcdr (elt), key);
+      tem = Fequal (XCONS (elt)->cdr, key);
       if (!NILP (tem)) return elt;
       QUIT;
     }
@@ -787,13 +812,13 @@ to be sure of changing the value of `foo'.")
       if (EQ (elt, tem))
        {
          if (NILP (prev))
-           list = Fcdr (tail);
+           list = XCONS (tail)->cdr;
          else
-           Fsetcdr (prev, Fcdr (tail));
+           Fsetcdr (prev, XCONS (tail)->cdr);
        }
       else
        prev = tail;
-      tail = Fcdr (tail);
+      tail = XCONS (tail)->cdr;
       QUIT;
     }
   return list;
@@ -821,13 +846,13 @@ to be sure of changing the value of `foo'.")
       if (! NILP (Fequal (elt, tem)))
        {
          if (NILP (prev))
-           list = Fcdr (tail);
+           list = XCONS (tail)->cdr;
          else
-           Fsetcdr (prev, Fcdr (tail));
+           Fsetcdr (prev, XCONS (tail)->cdr);
        }
       else
        prev = tail;
-      tail = Fcdr (tail);
+      tail = XCONS (tail)->cdr;
       QUIT;
     }
   return list;
@@ -861,17 +886,13 @@ See also the function `nreverse', which is used more often.")
   (list)
      Lisp_Object list;
 {
-  Lisp_Object length;
-  register Lisp_Object *vec;
-  register Lisp_Object tail;
-  register int i;
-
-  length = Flength (list);
-  vec = (Lisp_Object *) alloca (XINT (length) * sizeof (Lisp_Object));
-  for (i = XINT (length) - 1, tail = list; i >= 0; i--, tail = Fcdr (tail))
-    vec[i] = Fcar (tail);
+  Lisp_Object new;
 
-  return Flist (XINT (length), vec);
+  for (new = Qnil; CONSP (list); list = XCONS (list)->cdr)
+    new = Fcons (XCONS (list)->car, new);
+  if (!NILP (list))
+    wrong_type_argument (Qconsp, list);
+  return new;
 }
 \f
 Lisp_Object merge ();
@@ -979,12 +1000,12 @@ one of the properties on the list.")
      register Lisp_Object prop;
 {
   register Lisp_Object tail;
-  for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
+  for (tail = plist; !NILP (tail); tail = Fcdr (XCONS (tail)->cdr))
     {
       register Lisp_Object tem;
       tem = Fcar (tail);
       if (EQ (prop, tem))
-       return Fcar (Fcdr (tail));
+       return Fcar (XCONS (tail)->cdr);
     }
   return Qnil;
 }
@@ -1159,18 +1180,13 @@ internal_equal (o1, o2, depth)
       if (bcmp (XSTRING (o1)->data, XSTRING (o2)->data,
                XSTRING (o1)->size))
        return 0;
-#ifdef USE_TEXT_PROPERTIES
-      /* If the strings have intervals, verify they match;
-        if not, they are unequal.  */
-      if ((XSTRING (o1)->intervals != 0 || XSTRING (o2)->intervals != 0)
-         && ! compare_string_intervals (o1, o2))
-       return 0;
-#endif
       return 1;
     }
   return 0;
 }
 \f
+extern Lisp_Object Fmake_char_internal ();
+
 DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0,
   "Store each element of ARRAY with ITEM.\n\
 ARRAY is a vector, string, char-table, or bool-vector.")
@@ -1322,12 +1338,17 @@ or a character code.")
     return Faref (char_table, range);
   else if (VECTORP (range))
     {
-      int size = XVECTOR (range)->size;
-      Lisp_Object *val = XVECTOR (range)->contents;
-      Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
-                                           size <= 1 ? Qnil : val[1],
-                                           size <= 2 ? Qnil : val[2]);
-      return Faref (char_table, ch);
+      if (XVECTOR (range)->size == 1)
+       return Faref (char_table, XVECTOR (range)->contents[0]);
+      else
+       {
+         int size = XVECTOR (range)->size;
+         Lisp_Object *val = XVECTOR (range)->contents;
+         Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
+                                               size <= 1 ? Qnil : val[1],
+                                               size <= 2 ? Qnil : val[2]);
+         return Faref (char_table, ch);
+       }
     }
   else
     error ("Invalid RANGE argument to `char-table-range'");
@@ -1355,12 +1376,17 @@ or a character code.")
     Faset (char_table, range, value);
   else if (VECTORP (range))
     {
-      int size = XVECTOR (range)->size;
-      Lisp_Object *val = XVECTOR (range)->contents;
-      Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
-                                           size <= 1 ? Qnil : val[1],
-                                           size <= 2 ? Qnil : val[2]);
-      return Faset (char_table, ch, value);
+      if (XVECTOR (range)->size == 1)
+       return Faset (char_table, XVECTOR (range)->contents[0], value);
+      else
+       {
+         int size = XVECTOR (range)->size;
+         Lisp_Object *val = XVECTOR (range)->contents;
+         Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
+                                               size <= 1 ? Qnil : val[1],
+                                               size <= 2 ? Qnil : val[2]);
+         return Faset (char_table, ch, value);
+       }
     }
   else
     error ("Invalid RANGE argument to `set-char-table-range'");
@@ -1446,22 +1472,21 @@ map_char_table (c_function, function, subtable, arg, depth, indices)
     }
   else
     {
-      i = 32;
+      i = 0;
       to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
     }
 
-  for (i; i < to; i++)
+  for (; i < to; i++)
     {
       Lisp_Object elt = XCHAR_TABLE (subtable)->contents[i];
 
-      indices[depth] = i;
+      XSETFASTINT (indices[depth], i);
 
       if (SUB_CHAR_TABLE_P (elt))
        {
          if (depth >= 3)
            error ("Too deep char table");
-         map_char_table (c_function, function, elt, arg,
-                         depth + 1, indices);
+         map_char_table (c_function, function, elt, arg, depth + 1, indices);
        }
       else
        {
@@ -1483,15 +1508,16 @@ map_char_table (c_function, function, subtable, arg, depth, indices)
 
 DEFUN ("map-char-table", Fmap_char_table, Smap_char_table,
   2, 2, 0,
-  "Call FUNCTION for each range of like characters in CHAR-TABLE.\n\
+  "Call FUNCTION for each (normal and generic) characters in CHAR-TABLE.\n\
 FUNCTION is called with two arguments--a key and a value.\n\
-The key is always a possible RANGE argument to `set-char-table-range'.")
+The key is always a possible IDX argument to `aref'.")
   (function, char_table)
      Lisp_Object function, char_table;
 {
-  Lisp_Object keyvec;
   /* The depth of char table is at most 3. */
-  Lisp_Object *indices = (Lisp_Object *) alloca (3 * sizeof (Lisp_Object));
+  Lisp_Object indices[3];
+
+  CHECK_CHAR_TABLE (char_table, 1);
 
   map_char_table (NULL, function, char_table, char_table, 0, indices);
   return Qnil;
@@ -1601,7 +1627,7 @@ mapcar1 (leni, vals, fn, seq)
       for (i = 0; i < leni; i++)
        {
          vals[i] = call1 (fn, Fcar (tail));
-         tail = Fcdr (tail);
+         tail = XCONS (tail)->cdr;
        }
     }
 
@@ -1694,6 +1720,7 @@ Also accepts Space to mean yes, or Delete to mean no.")
 
 #ifdef HAVE_MENUS
       if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
+         && use_dialog_box
          && have_menus_p ())
        {
          Lisp_Object pane, menu;
@@ -1812,6 +1839,7 @@ and can edit it until it has been confirmed.")
 
 #ifdef HAVE_MENUS
   if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event)) 
+      && use_dialog_box
       && have_menus_p ())
     {
       Lisp_Object pane, menu, obj;
@@ -1931,7 +1959,7 @@ If FILENAME is omitted, the printname of FEATURE is used as the file name.")
       Vautoload_queue = Qt;
 
       Fload (NILP (file_name) ? Fsymbol_name (feature) : file_name,
-            Qnil, Qt, Qnil);
+            Qnil, Qt, Qnil, Qt);
 
       tem = Fmemq (feature, Vfeatures);
       if (NILP (tem))
@@ -1965,6 +1993,12 @@ syms_of_fns ()
 Used by `featurep' and `require', and altered by `provide'.");
   Vfeatures = Qnil;
 
+  DEFVAR_BOOL ("use-dialog-box", &use_dialog_box,
+    "*Non-nil means mouse commands use dialog boxes to ask questions.\n\
+This applies to y-or-n and yes-or-no questions asked by commands\n\
+invoked by mouse clicks and mouse menu items.");
+  use_dialog_box = 1;
+
   defsubr (&Sidentity);
   defsubr (&Srandom);
   defsubr (&Slength);