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