From xemacs-m  Tue Jul  1 13:09:34 1997
Received: from jagor.srce.hr (hniksic@jagor.srce.hr [161.53.2.130])
	by xemacs.org (8.8.5/8.8.5) with ESMTP id NAA09270
	for <xemacs-beta@xemacs.org>; Tue, 1 Jul 1997 13:09:32 -0500 (CDT)
Received: (from hniksic@localhost)
          by jagor.srce.hr (8.8.5/8.8.4)
	  id UAA10109; Tue, 1 Jul 1997 20:09:32 +0200 (MET DST)
To: XEmacs Developers <xemacs-beta@xemacs.org>
Subject: [PATCH] string-to-number accepts BASE argument
X-Attribution: Hrv
X-Face: Mie8:rOV<\c/~z{s.X4A{!?vY7{drJ([U]0O=W/<W*SMo/Mv:58:*_y~ki>xDi&N7XG
        KV^$k0m3Oe/)'e%3=$PCR&3ITUXH,cK>]bci&<qQ>Ff%x_>1`T(+M2Gg/fgndU%k*ft
        [(7._6e0n-V%|%'[c|q:;}td$#INd+;?!-V=c8Pqf}3J
From: Hrvoje Niksic <hniksic@srce.hr>
Date: 01 Jul 1997 20:09:31 +0200
Message-ID: <kigd8p21w6c.fsf@jagor.srce.hr>
Lines: 138
X-Mailer: Gnus v5.4.59/XEmacs 20.3(beta10) - "Athens"

This is the port of GNU Emacs capability.  I am still not sure what
this buys us, but I guess it doesn't hurt to have it.

--- etc/NEWS.orig	Tue Jul  1 19:48:46 1997
+++ etc/NEWS	Tue Jul  1 19:50:38 1997
@@ -238,6 +238,9 @@
 was set up as the terminal's erase character at the tim Emacs was
 started.
 
+** `string-to-number' now accepts an optional BASE argument which
+specifies which base to use.  The default base is 10.
+
 ** The TIME argument to `format-time-string' is now optional and
 defaults to the current time.
 
--- src/data.c.orig	Tue Jul  1 19:08:02 1997
+++ src/data.c	Tue Jul  1 19:30:58 1997
@@ -1244,18 +1244,54 @@
   return build_string (buffer);
 }
 
-DEFUN ("string-to-number", Fstring_to_number, 1, 1, 0, /*
+static int
+digit_to_number (int character, int base)
+{
+  int digit;
+
+  if (character >= '0' && character <= '9')
+    digit = character - '0';
+  else if (character >= 'a' && character <= 'z')
+    digit = character - 'a' + 10;
+  else if (character >= 'A' && character <= 'Z')
+    digit = character - 'A' + 10;
+  else
+    return -1;
+
+  if (digit >= base)
+    return -1;
+  else
+    return digit;
+}
+
+DEFUN ("string-to-number", Fstring_to_number, 1, 2, 0, /*
 Convert STRING to a number by parsing it as a decimal number.
 This parses both integers and floating point numbers.
 It ignores leading spaces and tabs.
+
+If BASE, interpret STRING as a number in that base.  If BASE isn't
+present, base 10 is used.  BASE must be between 2 and 16 (inclusive).
+Floating point numbers always use base 10.
 */
-       (string))
+       (string, base))
 {
-  Lisp_Object value;
   char *p;
+  int b;
+
   CHECK_STRING (string);
 
+  if (NILP (base))
+    b = 10;
+  else
+    {
+      CHECK_INT (base);
+      b = XINT (base);
+      if (b < 2 || b > 16)
+	Fsignal (Qargs_out_of_range, Fcons (base, Qnil));
+    }
+
   p = (char *) XSTRING_DATA (string);
+
   /* Skip any whitespace at the front of the number.  Some versions of
      atoi do this anyway, so we might as well make Emacs lisp consistent.  */
   while (*p == ' ' || *p == '\t')
@@ -1266,13 +1302,39 @@
     return make_float (atof (p));
 #endif /* LISP_FLOAT_TYPE */
 
-  if (sizeof (int) == sizeof (EMACS_INT))
-    XSETINT (value, atoi (p));
-  else if (sizeof (long) == sizeof (EMACS_INT))
-    XSETINT (value, atol (p));
+  if (base == 10)
+    {
+      /* Use the system-provided functions for base 10. */
+      Lisp_Object value;
+      if (sizeof (int) == sizeof (EMACS_INT))
+	XSETINT (value, atoi (p));
+      else if (sizeof (long) == sizeof (EMACS_INT))
+	XSETINT (value, atol (p));
+      else
+	abort ();
+      return value;
+    }
   else
-    abort ();
-  return value;
+    {
+      int digit, negative = 1;
+      EMACS_INT v = 0;
+
+      if (*p == '-')
+	{
+	  negative = -1;
+	  p++;
+	}
+      else if (*p == '+')
+	p++;  
+      while (1)
+	{
+	  digit = digit_to_number (*p++, b);
+	  if (digit < 0)
+	    break;
+	  v = v * b + digit;
+	}
+      return make_int (negative * v);
+    }
 }
   
 enum arithop
--- src/emacsfns.h.orig	Tue Jul  1 19:29:00 1997
+++ src/emacsfns.h	Tue Jul  1 19:29:02 1997
@@ -332,7 +332,7 @@
 
 Lisp_Object Fzerop (Lisp_Object);
 Lisp_Object Fnumber_to_string (Lisp_Object num);
-Lisp_Object Fstring_to_number (Lisp_Object str);
+Lisp_Object Fstring_to_number (Lisp_Object str, Lisp_Object base);
 Lisp_Object Fsubr_min_args (Lisp_Object subr);
 Lisp_Object Fsubr_max_args (Lisp_Object subr);
 


-- 
Hrvoje Niksic <hniksic@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
I'm sure they'll listen to reason! -- Neal Stevenson, _Snow Crash_

