]> code.delx.au - gnu-emacs/blobdiff - src/data.c
(message): Use message2, not message1.
[gnu-emacs] / src / data.c
index 613d9db6a64c77a52039e0d4b06f0dc9bb1f24cc..3e7a88fc7cdce820e5355f904556903cc9f05087 100644 (file)
@@ -1,5 +1,5 @@
 /* Primitive operations on Lisp data types for GNU Emacs Lisp interpreter.
-   Copyright (C) 1985, 1986, 1988, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1988, 1993 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -20,7 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include <signal.h>
 
-#include "config.h"
+#include <config.h>
 #include "lisp.h"
 #include "puresize.h"
 
@@ -31,16 +31,35 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "syssignal.h"
 
 #ifdef LISP_FLOAT_TYPE
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#endif
+
+/* Work around a problem that happens because math.h on hpux 7
+   defines two static variables--which, in Emacs, are not really static,
+   because `static' is defined as nothing.  The problem is that they are
+   here, in floatfns.c, and in lread.c.
+   These macros prevent the name conflict.  */
+#if defined (HPUX) && !defined (HPUX8)
+#define _MAXLDBL data_c_maxldbl
+#define _NMAXLDBL data_c_nmaxldbl
+#endif
+
 #include <math.h>
 #endif /* LISP_FLOAT_TYPE */
 
+#if !defined (atof)
+extern double atof ();
+#endif /* !atof */
+
 Lisp_Object Qnil, Qt, Qquote, Qlambda, Qsubr, Qunbound;
 Lisp_Object Qerror_conditions, Qerror_message, Qtop_level;
 Lisp_Object Qerror, Qquit, Qwrong_type_argument, Qargs_out_of_range;
 Lisp_Object Qvoid_variable, Qvoid_function, Qcyclic_function_indirection;
 Lisp_Object Qsetting_constant, Qinvalid_read_syntax;
 Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
-Lisp_Object Qend_of_file, Qarith_error;
+Lisp_Object Qend_of_file, Qarith_error, Qmark_inactive;
 Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
 Lisp_Object Qintegerp, Qnatnump, Qsymbolp, Qlistp, Qconsp;
 Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp;
@@ -518,6 +537,7 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
      register Lisp_Object sym, newdef;
 {
   CHECK_SYMBOL (sym, 0);
+
   if (!NILP (Vautoload_queue) && !EQ (XSYMBOL (sym)->function, Qunbound))
     Vautoload_queue = Fcons (Fcons (sym, XSYMBOL (sym)->function),
                             Vautoload_queue);
@@ -1211,9 +1231,9 @@ Lisp_Object
 indirect_function (object)
   register Lisp_Object object;
 {
-  Lisp_Object tortise, hare;
+  Lisp_Object tortoise, hare;
 
-  hare = tortise = object;
+  hare = tortoise = object;
 
   for (;;)
     {
@@ -1224,9 +1244,9 @@ indirect_function (object)
        break;
       hare = XSYMBOL (hare)->function;
 
-      tortise = XSYMBOL (tortise)->function;
+      tortoise = XSYMBOL (tortoise)->function;
 
-      if (EQ (hare, tortise))
+      if (EQ (hare, tortoise))
        Fsignal (Qcyclic_function_indirection, Fcons (object, Qnil));
     }
 
@@ -1476,7 +1496,7 @@ unsigned long
 cons_to_long (c)
      Lisp_Object c;
 {
-  int top, bot;
+  Lisp_Object top, bot;
   if (INTEGERP (c))
     return XINT (c);
   top = XCONS (c)->car;
@@ -1544,8 +1564,7 @@ enum arithop
 extern Lisp_Object float_arith_driver ();
 
 Lisp_Object
-arith_driver
-  (code, nargs, args)
+arith_driver (code, nargs, args)
      enum arithop code;
      int nargs;
      register Lisp_Object *args;
@@ -1601,7 +1620,12 @@ arith_driver
        case Amult: accum *= next; break;
        case Adiv:
          if (!argnum) accum = next;
-         else accum /= next;
+         else
+           {
+             if (next == 0)
+               Fsignal (Qarith_error, Qnil);
+             accum /= next;
+           }
          break;
        case Alogand: accum &= next; break;
        case Alogior: accum |= next; break;
@@ -1662,7 +1686,11 @@ float_arith_driver (accum, argnum, code, nargs, args)
          if (!argnum)
            accum = next;
          else
-           accum /= next;
+           {
+             if (next == 0)
+               Fsignal (Qarith_error, Qnil);
+             accum /= next;
+           }
          break;
        case Alogand:
        case Alogior:
@@ -1724,15 +1752,35 @@ The arguments must be numbers or markers.")
 
 DEFUN ("%", Frem, Srem, 2, 2, 0,
   "Returns remainder of first arg divided by second.\n\
-Both must be numbers or markers.")
+Both must be integers or markers.")
   (num1, num2)
      register Lisp_Object num1, num2;
 {
   Lisp_Object val;
 
+  CHECK_NUMBER_COERCE_MARKER (num1, 0);
+  CHECK_NUMBER_COERCE_MARKER (num2, 1);
+
+  if (XFASTINT (num2) == 0)
+    Fsignal (Qarith_error, Qnil);
+
+  XSET (val, Lisp_Int, XINT (num1) % XINT (num2));
+  return val;
+}
+
+DEFUN ("mod", Fmod, Smod, 2, 2, 0,
+  "Returns X modulo Y.\n\
+The result falls between zero (inclusive) and Y (exclusive).\n\
+Both X and Y must be numbers or markers.")
+  (num1, num2)
+     register Lisp_Object num1, num2;
+{
+  Lisp_Object val;
+  int i1, i2;
+
 #ifdef LISP_FLOAT_TYPE
   CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num1, 0);
-  CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num2, 0);
+  CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num2, 1);
 
   if (XTYPE (num1) == Lisp_Float || XTYPE (num2) == Lisp_Float)
     {
@@ -1740,12 +1788,16 @@ Both must be numbers or markers.")
 
       f1 = XTYPE (num1) == Lisp_Float ? XFLOAT (num1)->data : XINT (num1);
       f2 = XTYPE (num2) == Lisp_Float ? XFLOAT (num2)->data : XINT (num2);
+      if (f2 == 0)
+       Fsignal (Qarith_error, Qnil);
+
 #if defined (USG) || defined (sun) || defined (ultrix) || defined (hpux)
       f1 = fmod (f1, f2);
 #else
       f1 = drem (f1, f2);
 #endif
-      if (f1 < 0)
+      /* If the "remainder" comes out with the wrong sign, fix it.  */
+      if ((f1 < 0) != (f2 < 0))
        f1 += f2;
       return (make_float (f1));
     }
@@ -1754,7 +1806,19 @@ Both must be numbers or markers.")
   CHECK_NUMBER_COERCE_MARKER (num2, 1);
 #endif /* not LISP_FLOAT_TYPE */
 
-  XSET (val, Lisp_Int, XINT (num1) % XINT (num2));
+  i1 = XINT (num1);
+  i2 = XINT (num2);
+
+  if (i2 == 0)
+    Fsignal (Qarith_error, Qnil);
+  
+  i1 %= i2;
+
+  /* If the "remainder" comes out with the wrong sign, fix it.  */
+  if ((i1 < 0) != (i2 < 0))
+    i1 += i2;
+
+  XSET (val, Lisp_Int, i1);
   return val;
 }
 
@@ -1924,6 +1988,7 @@ syms_of_data ()
   Qbeginning_of_buffer = intern ("beginning-of-buffer");
   Qend_of_buffer = intern ("end-of-buffer");
   Qbuffer_read_only = intern ("buffer-read-only");
+  Qmark_inactive = intern ("mark-inactive");
 
   Qlistp = intern ("listp");
   Qconsp = intern ("consp");
@@ -2106,6 +2171,7 @@ syms_of_data ()
   staticpro (&Qbeginning_of_buffer);
   staticpro (&Qend_of_buffer);
   staticpro (&Qbuffer_read_only);
+  staticpro (&Qmark_inactive);
 
   staticpro (&Qlistp);
   staticpro (&Qconsp);
@@ -2198,6 +2264,7 @@ syms_of_data ()
   defsubr (&Stimes);
   defsubr (&Squo);
   defsubr (&Srem);
+  defsubr (&Smod);
   defsubr (&Smax);
   defsubr (&Smin);
   defsubr (&Slogand);