Unified · Split
| @@ -1817,234 +1817,152 @@ static void bn_zero(unsigned int *bn) · 1816 unmodified lines | ||
| 1817 | 1817 | current token */ |
| 1818 | 1818 | static void parse_number(const char *p) |
| 1819 | 1819 | { |
| 1820 | − int b, t, shift, frac_bits, s, exp_val, ch; | |
| 1821 | − char *q; | |
| 1822 | − unsigned int bn[BN_SIZE]; | |
| 1823 | − double d; | |
| 1824 | − | |
| 1825 | − /* number */ | |
| 1826 | − q = token_buf; | |
| 1827 | − ch = *p++; | |
| 1828 | − t = ch; | |
| 1829 | − ch = *p++; | |
| 1830 | − *q++ = t; | |
| 1820 | + int b, t, c; | |
| 1821 | + | |
| 1822 | + c = *p++; | |
| 1823 | + t = *p++; | |
| 1831 | 1824 | b = 10; |
| 1832 | − if (t == '.') { | |
| 1833 | − goto float_frac_parse; | |
| 1834 | − } else if (t == '0') { | |
| 1835 | − if (ch == 'x' || ch == 'X') { | |
| 1836 | − q--; | |
| 1837 | − ch = *p++; | |
| 1825 | + if(c=='.'){ | |
| 1826 | + --p; | |
| 1827 | + goto float_frac_parse; | |
| 1828 | + } | |
| 1829 | + if(c == '0'){ | |
| 1830 | + if (t == 'x' || t == 'X') { | |
| 1838 | 1831 | b = 16; |
| 1839 | − } else if (tcc_ext && (ch == 'b' || ch == 'B')) { | |
| 1840 | − q--; | |
| 1841 | − ch = *p++; | |
| 1832 | + c = *p++; | |
| 1833 | + } else if (tcc_ext && (t == 'b' || t == 'B')) { | |
| 1842 | 1834 | b = 2; |
| 1843 | − } | |
| 1844 | − } | |
| 1845 | − /* parse all digits. cannot check octal numbers at this stage | |
| 1846 | − because of floating point constants */ | |
| 1847 | − while (1) { | |
| 1848 | − if (ch >= 'a' && ch <= 'f') | |
| 1849 | − t = ch - 'a' + 10; | |
| 1850 | − else if (ch >= 'A' && ch <= 'F') | |
| 1851 | − t = ch - 'A' + 10; | |
| 1852 | − else if (isnum(ch)) | |
| 1853 | − t = ch - '0'; | |
| 1854 | − else | |
| 1855 | − break; | |
| 1856 | − if (t >= b) | |
| 1857 | − break; | |
| 1858 | − if (q >= token_buf + STRING_MAX_SIZE) { | |
| 1859 | − num_too_long: | |
| 1860 | − tcc_error("number too long"); | |
| 1861 | − } | |
| 1862 | − *q++ = ch; | |
| 1863 | − ch = *p++; | |
| 1864 | − } | |
| 1865 | − if (ch == '.' || | |
| 1866 | − ((ch == 'e' || ch == 'E') && b == 10) || | |
| 1867 | − ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) { | |
| 1868 | − if (b != 10) { | |
| 1869 | − /* NOTE: strtox should support that for hexa numbers, but | |
| 1870 | − non ISOC99 libcs do not support it, so we prefer to do | |
| 1871 | − it by hand */ | |
| 1872 | − /* hexadecimal or binary floats */ | |
| 1873 | − /* XXX: handle overflows */ | |
| 1874 | − *q = '\0'; | |
| 1875 | − if (b == 16) | |
| 1876 | − shift = 4; | |
| 1877 | − else | |
| 1878 | − shift = 2; | |
| 1879 | − bn_zero(bn); | |
| 1880 | − q = token_buf; | |
| 1881 | − while (1) { | |
| 1882 | − t = *q++; | |
| 1883 | − if (t == '\0') { | |
| 1884 | − break; | |
| 1885 | − } else if (t >= 'a') { | |
| 1886 | − t = t - 'a' + 10; | |
| 1887 | − } else if (t >= 'A') { | |
| 1888 | − t = t - 'A' + 10; | |
| 1889 | − } else { | |
| 1890 | − t = t - '0'; | |
| 1891 | − } | |
| 1892 | − bn_lshift(bn, shift, t); | |
| 1893 | − } | |
| 1894 | − frac_bits = 0; | |
| 1895 | − if (ch == '.') { | |
| 1896 | − ch = *p++; | |
| 1897 | − while (1) { | |
| 1898 | − t = ch; | |
| 1899 | − if (t >= 'a' && t <= 'f') { | |
| 1900 | − t = t - 'a' + 10; | |
| 1901 | − } else if (t >= 'A' && t <= 'F') { | |
| 1902 | − t = t - 'A' + 10; | |
| 1903 | − } else if (t >= '0' && t <= '9') { | |
| 1904 | − t = t - '0'; | |
| 1905 | − } else { | |
| 1906 | − break; | |
| 1907 | − } | |
| 1908 | − if (t >= b) | |
| 1909 | − tcc_error("invalid digit"); | |
| 1910 | − bn_lshift(bn, shift, t); | |
| 1911 | − frac_bits += shift; | |
| 1912 | − ch = *p++; | |
| 1913 | − } | |
| 1914 | − } | |
| 1915 | − if (ch != 'p' && ch != 'P') | |
| 1835 | + c = *p++; | |
| 1836 | + }else{ | |
| 1837 | + --p; | |
| 1838 | + } | |
| 1839 | + }else | |
| 1840 | + --p; | |
| 1841 | + if(strchr(p , '.') || (b == 10 && (strchr(p,'e') || strchr(p,'E'))) || | |
| 1842 | + ((b == 2 || b == 16)&& (strchr(p,'p') || strchr(p,'P')))){ | |
| 1843 | + long double ld, sh, fb; | |
| 1844 | + int exp; | |
| 1845 | + /* NOTE: strtox should support that for hexa numbers, but | |
| 1846 | + non ISOC99 libcs do not support it, so we prefer to do | |
| 1847 | + it by hand */ | |
| 1848 | + /* hexadecimal or binary floats */ | |
| 1849 | + /* XXX: handle overflows */ | |
| 1850 | +float_frac_parse: | |
| 1851 | + fb = 1.0L/b; | |
| 1852 | + sh = b; | |
| 1853 | + ld = 0.0; | |
| 1854 | + | |
| 1855 | + while(1){ | |
| 1856 | + if (c == '\0') | |
| 1857 | + break; | |
| 1858 | + if (c >= 'a' && c <= 'f') | |
| 1859 | + t = c - 'a' + 10; | |
| 1860 | + else if (c >= 'A' && c <= 'F') | |
| 1861 | + t = c - 'A' + 10; | |
| 1862 | + else if(isnum(c)) | |
| 1863 | + t = c - '0'; | |
| 1864 | + else | |
| 1865 | + break; | |
| 1866 | + if (t >= b) | |
| 1867 | + tcc_error("invalid digit"); | |
| 1868 | + ld = ld * b + t; | |
| 1869 | + c = *p++; | |
| 1870 | + } | |
| 1871 | + if (c == '.'){ | |
| 1872 | + c = *p++; | |
| 1873 | + sh = fb; | |
| 1874 | + while (1){ | |
| 1875 | + if (c == '\0') | |
| 1876 | + break; | |
| 1877 | + if (c >= 'a' && c <= 'f') | |
| 1878 | + t = c - 'a' + 10; | |
| 1879 | + else if (c >= 'A' && c <= 'F') | |
| 1880 | + t = c - 'A' + 10; | |
| 1881 | + else if (isnum(c)) | |
| 1882 | + t =c - '0'; | |
| 1883 | + else | |
| 1884 | + break; | |
| 1885 | + if (t >= b){ | |
| 1886 | + if(b == 10 && (c == 'e' || c == 'E' || c == 'f' || c == 'F')) | |
| 1887 | + break; | |
| 1888 | + tcc_error("invalid digit"); | |
| 1889 | + } | |
| 1890 | + ld += sh*t; | |
| 1891 | + sh*=fb; | |
| 1892 | + c = *p++; | |
| 1893 | + } | |
| 1894 | + } | |
| 1895 | + if ((b == 16 || b == 2) && c != 'p' && c != 'P') | |
| 1916 | 1896 | expect("exponent"); |
| 1917 | − ch = *p++; | |
| 1918 | − s = 1; | |
| 1919 | − exp_val = 0; | |
| 1920 | − if (ch == '+') { | |
| 1921 | − ch = *p++; | |
| 1922 | − } else if (ch == '-') { | |
| 1923 | − s = -1; | |
| 1924 | − ch = *p++; | |
| 1925 | − } | |
| 1926 | − if (ch < '0' || ch > '9') | |
| 1927 | − expect("exponent digits"); | |
| 1928 | − while (ch >= '0' && ch <= '9') { | |
| 1929 | − exp_val = exp_val * 10 + ch - '0'; | |
| 1930 | − ch = *p++; | |
| 1931 | − } | |
| 1932 | − exp_val = exp_val * s; | |
| 1933 | − | |
| 1934 | − /* now we can generate the number */ | |
| 1935 | − /* XXX: should patch directly float number */ | |
| 1936 | − d = (double)bn[1] * 4294967296.0 + (double)bn[0]; | |
| 1937 | − d = ldexp(d, exp_val - frac_bits); | |
| 1938 | − t = toup(ch); | |
| 1939 | − if (t == 'F') { | |
| 1940 | − ch = *p++; | |
| 1941 | − tok = TOK_CFLOAT; | |
| 1942 | − /* float : should handle overflow */ | |
| 1943 | − tokc.f = (float)d; | |
| 1944 | − } else if (t == 'L') { | |
| 1945 | − ch = *p++; | |
| 1897 | + if(((c == 'e' || c == 'E') && b == 10) || | |
| 1898 | + ((c == 'p' || c == 'P') && (b == 16 || b == 2))){ | |
| 1899 | + c = *p++; | |
| 1900 | + if(c == '+' || c == '-'){ | |
| 1901 | + if (c == '-') | |
| 1902 | + sh = fb; | |
| 1903 | + c = *p++; | |
| 1904 | + }else | |
| 1905 | + sh = b; | |
| 1906 | + if (!isnum(c)) | |
| 1907 | + expect("exponent digits"); | |
| 1908 | + exp = 0; | |
| 1909 | + do{ | |
| 1910 | + exp = exp * 10 + c - '0'; | |
| 1911 | + c = *p++; | |
| 1912 | + }while(isnum(c)); | |
| 1913 | + while (exp != 0){ | |
| 1914 | + if (exp & 1) | |
| 1915 | + ld *= sh; | |
| 1916 | + exp >>= 1; | |
| 1917 | + sh *= sh; | |
| 1918 | + } | |
| 1919 | + } | |
| 1920 | + t = toup(c); | |
| 1921 | + if (t == 'F') { | |
| 1922 | + c = *p++; | |
| 1923 | + tok = TOK_CFLOAT; | |
| 1924 | + tokc.f = (float)ld; | |
| 1925 | + } else if (t == 'L') { | |
| 1926 | + c = *p++; | |
| 1946 | 1927 | #ifdef TCC_TARGET_PE |
| 1947 | − tok = TOK_CDOUBLE; | |
| 1948 | − tokc.d = d; | |
| 1928 | + tok = TOK_CDOUBLE; | |
| 1929 | + tokc.d = (double)ld; | |
| 1949 | 1930 | #else |
| 1950 | − tok = TOK_CLDOUBLE; | |
| 1951 | − /* XXX: not large enough */ | |
| 1952 | − tokc.ld = (long double)d; | |
| 1931 | + tok = TOK_CLDOUBLE; | |
| 1932 | + tokc.ld = ld; | |
| 1953 | 1933 | #endif |
| 1954 | − } else { | |
| 1955 | − tok = TOK_CDOUBLE; | |
| 1956 | − tokc.d = d; | |
| 1957 | − } | |
| 1958 | − } else { | |
| 1959 | − /* decimal floats */ | |
| 1960 | − if (ch == '.') { | |
| 1961 | − if (q >= token_buf + STRING_MAX_SIZE) | |
| 1962 | − goto num_too_long; | |
| 1963 | − *q++ = ch; | |
| 1964 | − ch = *p++; | |
| 1965 | − float_frac_parse: | |
| 1966 | − while (ch >= '0' && ch <= '9') { | |
| 1967 | − if (q >= token_buf + STRING_MAX_SIZE) | |
| 1968 | − goto num_too_long; | |
| 1969 | − *q++ = ch; | |
| 1970 | − ch = *p++; | |
| 1971 | − } | |
| 1972 | − } | |
| 1973 | − if (ch == 'e' || ch == 'E') { | |
| 1974 | − if (q >= token_buf + STRING_MAX_SIZE) | |
| 1975 | − goto num_too_long; | |
| 1976 | − *q++ = ch; | |
| 1977 | − ch = *p++; | |
| 1978 | − if (ch == '-' || ch == '+') { | |
| 1979 | − if (q >= token_buf + STRING_MAX_SIZE) | |
| 1980 | − goto num_too_long; | |
| 1981 | − *q++ = ch; | |
| 1982 | − ch = *p++; | |
| 1983 | − } | |
| 1984 | − if (ch < '0' || ch > '9') | |
| 1985 | − expect("exponent digits"); | |
| 1986 | − while (ch >= '0' && ch <= '9') { | |
| 1987 | − if (q >= token_buf + STRING_MAX_SIZE) | |
| 1988 | − goto num_too_long; | |
| 1989 | − *q++ = ch; | |
| 1990 | − ch = *p++; | |
| 1991 | − } | |
| 1992 | − } | |
| 1993 | − *q = '\0'; | |
| 1994 | − t = toup(ch); | |
| 1995 | − errno = 0; | |
| 1996 | − if (t == 'F') { | |
| 1997 | − ch = *p++; | |
| 1998 | − tok = TOK_CFLOAT; | |
| 1999 | − tokc.f = strtof(token_buf, NULL); | |
| 2000 | − } else if (t == 'L') { | |
| 2001 | − ch = *p++; | |
| 2002 | −#ifdef TCC_TARGET_PE | |
| 2003 | − tok = TOK_CDOUBLE; | |
| 2004 | − tokc.d = strtod(token_buf, NULL); | |
| 2005 | −#else | |
| 2006 | − tok = TOK_CLDOUBLE; | |
| 2007 | − tokc.ld = strtold(token_buf, NULL); | |
| 2008 | −#endif | |
| 2009 | − } else { | |
| 2010 | − tok = TOK_CDOUBLE; | |
| 2011 | − tokc.d = strtod(token_buf, NULL); | |
| 2012 | − } | |
| 2013 | − } | |
| 1934 | + } else { | |
| 1935 | + tok = TOK_CDOUBLE; | |
| 1936 | + tokc.d = (double)ld; | |
| 1937 | + } | |
| 2014 | 1938 | } else { |
| 2015 | − unsigned long long n, n1; | |
| 1939 | + uint64_t n = 0, n1; | |
| 1940 | + int warn = 1; | |
| 2016 | 1941 | int lcount, ucount; |
| 2017 | − | |
| 2018 | − /* integer number */ | |
| 2019 | − *q = '\0'; | |
| 2020 | − q = token_buf; | |
| 2021 | − if (b == 10 && *q == '0') { | |
| 1942 | + if (b == 10 && c == '0') { | |
| 2022 | 1943 | b = 8; |
| 2023 | − q++; | |
| 2024 | − } | |
| 2025 | − n = 0; | |
| 2026 | − while(1) { | |
| 2027 | − t = *q++; | |
| 2028 | − /* no need for checks except for base 10 / 8 errors */ | |
| 2029 | − if (t == '\0') { | |
| 2030 | − break; | |
| 2031 | − } else if (t >= 'a') { | |
| 2032 | − t = t - 'a' + 10; | |
| 2033 | − } else if (t >= 'A') { | |
| 2034 | − t = t - 'A' + 10; | |
| 2035 | − } else { | |
| 2036 | − t = t - '0'; | |
| 2037 | − if (t >= b) | |
| 2038 | − tcc_error("invalid digit"); | |
| 2039 | − } | |
| 2040 | − n1 = n; | |
| 2041 | − n = n * b + t; | |
| 2042 | − /* detect overflow */ | |
| 2043 | − /* XXX: this test is not reliable */ | |
| 2044 | − if (n < n1) | |
| 2045 | − tcc_error("integer constant overflow"); | |
| 2046 | 1944 | } |
| 2047 | − | |
| 1945 | + while(1){ | |
| 1946 | + if (c == '\0') | |
| 1947 | + break; | |
| 1948 | + if (c >= 'a' && c <= 'f') | |
| 1949 | + t = c - 'a' + 10; | |
| 1950 | + else if (c >= 'A' && c <= 'F') | |
| 1951 | + t = c - 'A' + 10; | |
| 1952 | + else if(isnum(c)) | |
| 1953 | + t = c - '0'; | |
| 1954 | + else | |
| 1955 | + break; | |
| 1956 | + if (t >= b) | |
| 1957 | + tcc_error("invalid digit"); | |
| 1958 | + n1 = n; | |
| 1959 | + n = n * b + t; | |
| 1960 | + if (n < n1 && warn){ | |
| 1961 | + tcc_warning("integer constant overflow"); | |
| 1962 | + warn = 0; | |
| 1963 | + } | |
| 1964 | + c = *p++; | |
| 1965 | + } | |
| 2048 | 1966 | /* XXX: not exactly ANSI compliant */ |
| 2049 | 1967 | if ((n & 0xffffffff00000000LL) != 0) { |
| 2050 | 1968 | if ((n >> 63) != 0) |
| @@ -2059,7 +1977,7 @@ static void parse_number(const char *p) · 8 unmodified lines | ||
| 2059 | 1977 | lcount = 0; |
| 2060 | 1978 | ucount = 0; |
| 2061 | 1979 | for(;;) { |
| 2062 | − t = toup(ch); | |
| 1980 | + t = toup(c); | |
| 2063 | 1981 | if (t == 'L') { |
| 2064 | 1982 | if (lcount >= 2) |
| 2065 | 1983 | tcc_error("three 'l's in integer constant"); |
| @@ -2074,7 +1992,7 @@ static void parse_number(const char *p) · 8 unmodified lines | ||
| 2074 | 1992 | #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE |
| 2075 | 1993 | } |
| 2076 | 1994 | #endif |
| 2077 | − ch = *p++; | |
| 1995 | + c = *p++; | |
| 2078 | 1996 | } else if (t == 'U') { |
| 2079 | 1997 | if (ucount >= 1) |
| 2080 | 1998 | tcc_error("two 'u's in integer constant"); |
| @@ -2083,7 +2001,7 @@ static void parse_number(const char *p) · 2 unmodified lines | ||
| 2083 | 2001 | tok = TOK_CUINT; |
| 2084 | 2002 | else if (tok == TOK_CLLONG) |
| 2085 | 2003 | tok = TOK_CULLONG; |
| 2086 | − ch = *p++; | |
| 2004 | + c = *p++; | |
| 2087 | 2005 | } else { |
| 2088 | 2006 | break; |
| 2089 | 2007 | } |
| @@ -2093,7 +2011,7 @@ static void parse_number(const char *p) · 3 unmodified lines | ||
| 2093 | 2011 | else |
| 2094 | 2012 | tokc.ull = n; |
| 2095 | 2013 | } |
| 2096 | − if (ch) | |
| 2014 | + if (c) | |
| 2097 | 2015 | tcc_error("invalid number\n"); |
| 2098 | 2016 | } |
| 2099 | 2017 | |