diff options
| author | Richard M. Stallman | 1997-05-12 22:04:18 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1997-05-12 22:04:18 +0000 |
| commit | 3883fbebaa0039aa14b28302f64ab8f0752647d8 (patch) | |
| tree | 7eeedc656d369e9e1b3ae48fbbeaea10ee9c6b57 /src | |
| parent | abb4b7ec87986568cb49fde5b01c61c7e7ab325d (diff) | |
| download | emacs-3883fbebaa0039aa14b28302f64ab8f0752647d8.tar.gz emacs-3883fbebaa0039aa14b28302f64ab8f0752647d8.zip | |
(wrong_type_argument): Pass new arg to Fstring_to_number.
(Fstring_to_number): Handle bases 2...16.
(digit_to_number): New subroutine.
Diffstat (limited to 'src')
| -rw-r--r-- | src/data.c | 75 |
1 files changed, 61 insertions, 14 deletions
diff --git a/src/data.c b/src/data.c index da8f207fb53..da67d54b97a 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -112,7 +112,7 @@ wrong_type_argument (predicate, value) | |||
| 112 | { | 112 | { |
| 113 | if (STRINGP (value) && | 113 | if (STRINGP (value) && |
| 114 | (EQ (predicate, Qintegerp) || EQ (predicate, Qinteger_or_marker_p))) | 114 | (EQ (predicate, Qintegerp) || EQ (predicate, Qinteger_or_marker_p))) |
| 115 | return Fstring_to_number (value); | 115 | return Fstring_to_number (value, Qnil); |
| 116 | if (INTEGERP (value) && EQ (predicate, Qstringp)) | 116 | if (INTEGERP (value) && EQ (predicate, Qstringp)) |
| 117 | return Fnumber_to_string (value); | 117 | return Fnumber_to_string (value); |
| 118 | } | 118 | } |
| @@ -1912,18 +1912,54 @@ NUMBER may be an integer or a floating point number.") | |||
| 1912 | return build_string (buffer); | 1912 | return build_string (buffer); |
| 1913 | } | 1913 | } |
| 1914 | 1914 | ||
| 1915 | DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 1, 0, | 1915 | INLINE static int |
| 1916 | digit_to_number (character, base) | ||
| 1917 | int character, base; | ||
| 1918 | { | ||
| 1919 | int digit; | ||
| 1920 | |||
| 1921 | if (character >= '0' && character <= '9') | ||
| 1922 | digit = character - '0'; | ||
| 1923 | else if (character >= 'a' && character <= 'z') | ||
| 1924 | digit = character - 'a' + 10; | ||
| 1925 | else if (character >= 'A' && character <= 'Z') | ||
| 1926 | digit = character - 'A' + 10; | ||
| 1927 | else | ||
| 1928 | return -1; | ||
| 1929 | |||
| 1930 | if (digit >= base) | ||
| 1931 | return -1; | ||
| 1932 | else | ||
| 1933 | return digit; | ||
| 1934 | } | ||
| 1935 | |||
| 1936 | DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0, | ||
| 1916 | "Convert STRING to a number by parsing it as a decimal number.\n\ | 1937 | "Convert STRING to a number by parsing it as a decimal number.\n\ |
| 1917 | This parses both integers and floating point numbers.\n\ | 1938 | This parses both integers and floating point numbers.\n\ |
| 1918 | It ignores leading spaces and tabs.") | 1939 | It ignores leading spaces and tabs.\n\ |
| 1919 | (string) | 1940 | \n\ |
| 1920 | register Lisp_Object string; | 1941 | If BASE, interpret STRING as a number in that base. If BASE isn't\n\ |
| 1942 | present, base 10 is used. BASE must be between 2 and 16 (inclusive).\n\ | ||
| 1943 | Floating point numbers always use base 10.") | ||
| 1944 | (string, base) | ||
| 1945 | register Lisp_Object string, base; | ||
| 1921 | { | 1946 | { |
| 1922 | Lisp_Object value; | 1947 | register unsigned char *p; |
| 1923 | unsigned char *p; | 1948 | register int b, digit, v = 0; |
| 1949 | int negative = 1; | ||
| 1924 | 1950 | ||
| 1925 | CHECK_STRING (string, 0); | 1951 | CHECK_STRING (string, 0); |
| 1926 | 1952 | ||
| 1953 | if (NILP (base)) | ||
| 1954 | b = 10; | ||
| 1955 | else | ||
| 1956 | { | ||
| 1957 | CHECK_NUMBER (base, 1); | ||
| 1958 | b = XINT (base); | ||
| 1959 | if (b < 2 || b > 16) | ||
| 1960 | Fsignal (Qargs_out_of_range, Fcons (base, Qnil)); | ||
| 1961 | } | ||
| 1962 | |||
| 1927 | p = XSTRING (string)->data; | 1963 | p = XSTRING (string)->data; |
| 1928 | 1964 | ||
| 1929 | /* Skip any whitespace at the front of the number. Some versions of | 1965 | /* Skip any whitespace at the front of the number. Some versions of |
| @@ -1931,19 +1967,30 @@ It ignores leading spaces and tabs.") | |||
| 1931 | while (*p == ' ' || *p == '\t') | 1967 | while (*p == ' ' || *p == '\t') |
| 1932 | p++; | 1968 | p++; |
| 1933 | 1969 | ||
| 1970 | if (*p == '-') | ||
| 1971 | { | ||
| 1972 | negative = -1; | ||
| 1973 | p++; | ||
| 1974 | } | ||
| 1975 | else if (*p == '+') | ||
| 1976 | p++; | ||
| 1977 | |||
| 1934 | #ifdef LISP_FLOAT_TYPE | 1978 | #ifdef LISP_FLOAT_TYPE |
| 1935 | if (isfloat_string (p)) | 1979 | if (isfloat_string (p)) |
| 1936 | return make_float (atof (p)); | 1980 | return make_float (atof (p)); |
| 1937 | #endif /* LISP_FLOAT_TYPE */ | 1981 | #endif /* LISP_FLOAT_TYPE */ |
| 1938 | 1982 | ||
| 1939 | if (sizeof (int) == sizeof (EMACS_INT)) | 1983 | while (1) |
| 1940 | XSETINT (value, atoi (p)); | 1984 | { |
| 1941 | else if (sizeof (long) == sizeof (EMACS_INT)) | 1985 | int digit = digit_to_number (*p++, b); |
| 1942 | XSETINT (value, atol (p)); | 1986 | if (digit < 0) |
| 1943 | else | 1987 | break; |
| 1944 | abort (); | 1988 | v = v * b + digit; |
| 1945 | return value; | 1989 | } |
| 1990 | |||
| 1991 | return make_number (negative * v); | ||
| 1946 | } | 1992 | } |
| 1993 | |||
| 1947 | 1994 | ||
| 1948 | enum arithop | 1995 | enum arithop |
| 1949 | { Aadd, Asub, Amult, Adiv, Alogand, Alogior, Alogxor, Amax, Amin }; | 1996 | { Aadd, Asub, Amult, Adiv, Alogand, Alogior, Alogxor, Amax, Amin }; |