Make identifiers static if they are not used in other modules.
[bpt/emacs.git] / src / data.c
index 78bd454..57d7753 100644 (file)
@@ -90,7 +90,8 @@ static Lisp_Object Qsymbol, Qstring, Qcons, Qmarker, Qoverlay;
 Lisp_Object Qwindow;
 static Lisp_Object Qfloat, Qwindow_configuration;
 static Lisp_Object Qprocess;
-Lisp_Object Qcompiled_function, Qbuffer, Qframe, Qvector;
+static Lisp_Object Qcompiled_function, Qframe, Qvector;
+Lisp_Object Qbuffer;
 static Lisp_Object Qchar_table, Qbool_vector, Qhash_table;
 static Lisp_Object Qsubrp, Qmany, Qunevalled;
 Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
@@ -2326,33 +2327,110 @@ DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0,
   return Qnil;
 }
 \f
-/* Convert between long values and pairs of Lisp integers.
-   Note that long_to_cons returns a single Lisp integer
-   when the value fits in one.  */
+/* Convert the cons-of-integers, integer, or float value C to an
+   unsigned value with maximum value MAX.  Signal an error if C does not
+   have a valid format or is out of range.  */
+uintmax_t
+cons_to_unsigned (Lisp_Object c, uintmax_t max)
+{
+  int valid = 0;
+  uintmax_t val IF_LINT (= 0);
+  if (INTEGERP (c))
+    {
+      valid = 0 <= XINT (c);
+      val = XINT (c);
+    }
+  else if (FLOATP (c))
+    {
+      double d = XFLOAT_DATA (c);
+      if (0 <= d
+         && d < (max == UINTMAX_MAX ? (double) UINTMAX_MAX + 1 : max + 1))
+       {
+         val = d;
+         valid = 1;
+       }
+    }
+  else if (CONSP (c) && NATNUMP (XCAR (c)))
+    {
+      uintmax_t top = XFASTINT (XCAR (c));
+      Lisp_Object rest = XCDR (c);
+      if (top <= UINTMAX_MAX >> 24 >> 16
+         && CONSP (rest)
+         && NATNUMP (XCAR (rest)) && XFASTINT (XCAR (rest)) < 1 << 24
+         && NATNUMP (XCDR (rest)) && XFASTINT (XCDR (rest)) < 1 << 16)
+       {
+         uintmax_t mid = XFASTINT (XCAR (rest));
+         val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest));
+         valid = 1;
+       }
+      else if (top <= UINTMAX_MAX >> 16)
+       {
+         if (CONSP (rest))
+           rest = XCAR (rest);
+         if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16)
+           {
+             val = top << 16 | XFASTINT (rest);
+             valid = 1;
+           }
+       }
+    }
 
-Lisp_Object
-long_to_cons (long unsigned int i)
-{
-  unsigned long top = i >> 16;
-  unsigned int bot = i & 0xFFFF;
-  if (top == 0)
-    return make_number (bot);
-  if (top == (unsigned long)-1 >> 16)
-    return Fcons (make_number (-1), make_number (bot));
-  return Fcons (make_number (top), make_number (bot));
+  if (! (valid && val <= max))
+    error ("Not an in-range integer, float, or cons of integers");
+  return val;
 }
 
-unsigned long
-cons_to_long (Lisp_Object c)
+/* Convert the cons-of-integers, integer, or float value C to a signed
+   value with extrema MIN and MAX.  Signal an error if C does not have
+   a valid format or is out of range.  */
+intmax_t
+cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max)
 {
-  Lisp_Object top, bot;
+  int valid = 0;
+  intmax_t val IF_LINT (= 0);
   if (INTEGERP (c))
-    return XINT (c);
-  top = XCAR (c);
-  bot = XCDR (c);
-  if (CONSP (bot))
-    bot = XCAR (bot);
-  return ((XINT (top) << 16) | XINT (bot));
+    {
+      val = XINT (c);
+      valid = 1;
+    }
+  else if (FLOATP (c))
+    {
+      double d = XFLOAT_DATA (c);
+      if (min <= d
+         && d < (max == INTMAX_MAX ? (double) INTMAX_MAX + 1 : max + 1))
+       {
+         val = d;
+         valid = 1;
+       }
+    }
+  else if (CONSP (c) && INTEGERP (XCAR (c)))
+    {
+      intmax_t top = XINT (XCAR (c));
+      Lisp_Object rest = XCDR (c);
+      if (INTMAX_MIN >> 24 >> 16 <= top && top <= INTMAX_MAX >> 24 >> 16
+         && CONSP (rest)
+         && NATNUMP (XCAR (rest)) && XFASTINT (XCAR (rest)) < 1 << 24
+         && NATNUMP (XCDR (rest)) && XFASTINT (XCDR (rest)) < 1 << 16)
+       {
+         intmax_t mid = XFASTINT (XCAR (rest));
+         val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest));
+         valid = 1;
+       }
+      else if (INTMAX_MIN >> 16 <= top && top <= INTMAX_MAX >> 16)
+       {
+         if (CONSP (rest))
+           rest = XCAR (rest);
+         if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16)
+           {
+             val = top << 16 | XFASTINT (rest);
+             valid = 1;
+           }
+       }
+    }
+
+  if (! (valid && min <= val && val <= max))
+    error ("Not an in-range integer, float, or cons of integers");
+  return val;
 }
 \f
 DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0,