|
1 | | - /* |
| 1 | +/* |
2 | 2 | * simplecpp - A simple and high-fidelity C/C++ preprocessor library |
3 | 3 | * Copyright (C) 2016 Daniel Marjamäki. |
4 | 4 | * |
@@ -1755,161 +1755,159 @@ namespace simplecpp { |
1755 | 1755 | } |
1756 | 1756 | } |
1757 | 1757 |
|
1758 | | -namespace { |
1759 | | - /** Evaluate sizeof(type) */ |
1760 | | - void simplifySizeof(simplecpp::TokenList &expr, const std::map<std::string, std::size_t> &sizeOfType) |
1761 | | - { |
1762 | | - for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) { |
1763 | | - if (tok->str != "sizeof") |
1764 | | - continue; |
1765 | | - simplecpp::Token *tok1 = tok->next; |
1766 | | - if (!tok1) { |
1767 | | - throw std::runtime_error("missed sizeof argument"); |
1768 | | - } |
1769 | | - simplecpp::Token *tok2 = tok1->next; |
1770 | | - if (!tok2) { |
1771 | | - throw std::runtime_error("missed sizeof argument"); |
1772 | | - } |
1773 | | - if (tok1->op == '(') { |
1774 | | - tok1 = tok1->next; |
1775 | | - while (tok2->op != ')') |
1776 | | - tok2 = tok2->next; |
1777 | | - } |
1778 | | - |
1779 | | - std::string type; |
1780 | | - for (simplecpp::Token *typeToken = tok1; typeToken != tok2; typeToken = typeToken->next) { |
1781 | | - if ((typeToken->str == "unsigned" || typeToken->str == "signed") && typeToken->next->name) |
1782 | | - continue; |
1783 | | - if (typeToken->str == "*" && type.find('*') != std::string::npos) |
1784 | | - continue; |
1785 | | - if (!type.empty()) |
1786 | | - type += ' '; |
1787 | | - type += typeToken->str; |
1788 | | - } |
| 1758 | +/** Evaluate sizeof(type) */ |
| 1759 | +static void simplifySizeof(simplecpp::TokenList &expr, const std::map<std::string, std::size_t> &sizeOfType) |
| 1760 | +{ |
| 1761 | + for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) { |
| 1762 | + if (tok->str != "sizeof") |
| 1763 | + continue; |
| 1764 | + simplecpp::Token *tok1 = tok->next; |
| 1765 | + if (!tok1) { |
| 1766 | + throw std::runtime_error("missed sizeof argument"); |
| 1767 | + } |
| 1768 | + simplecpp::Token *tok2 = tok1->next; |
| 1769 | + if (!tok2) { |
| 1770 | + throw std::runtime_error("missed sizeof argument"); |
| 1771 | + } |
| 1772 | + if (tok1->op == '(') { |
| 1773 | + tok1 = tok1->next; |
| 1774 | + while (tok2->op != ')') |
| 1775 | + tok2 = tok2->next; |
| 1776 | + } |
1789 | 1777 |
|
1790 | | - const std::map<std::string, std::size_t>::const_iterator it = sizeOfType.find(type); |
1791 | | - if (it != sizeOfType.end()) |
1792 | | - tok->setstr(toString(it->second)); |
1793 | | - else |
| 1778 | + std::string type; |
| 1779 | + for (simplecpp::Token *typeToken = tok1; typeToken != tok2; typeToken = typeToken->next) { |
| 1780 | + if ((typeToken->str == "unsigned" || typeToken->str == "signed") && typeToken->next->name) |
1794 | 1781 | continue; |
1795 | | - |
1796 | | - tok2 = tok2->next; |
1797 | | - while (tok->next != tok2) |
1798 | | - expr.deleteToken(tok->next); |
| 1782 | + if (typeToken->str == "*" && type.find('*') != std::string::npos) |
| 1783 | + continue; |
| 1784 | + if (!type.empty()) |
| 1785 | + type += ' '; |
| 1786 | + type += typeToken->str; |
1799 | 1787 | } |
| 1788 | + |
| 1789 | + const std::map<std::string, std::size_t>::const_iterator it = sizeOfType.find(type); |
| 1790 | + if (it != sizeOfType.end()) |
| 1791 | + tok->setstr(toString(it->second)); |
| 1792 | + else |
| 1793 | + continue; |
| 1794 | + |
| 1795 | + tok2 = tok2->next; |
| 1796 | + while (tok->next != tok2) |
| 1797 | + expr.deleteToken(tok->next); |
1800 | 1798 | } |
| 1799 | +} |
1801 | 1800 |
|
1802 | | - const char * const altopData[] = {"and","or","bitand","bitor","not","not_eq","xor"}; |
1803 | | - const std::set<std::string> altop(&altopData[0], &altopData[7]); |
1804 | | - void simplifyName(simplecpp::TokenList &expr) |
1805 | | - { |
1806 | | - for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) { |
1807 | | - if (tok->name) { |
1808 | | - if (altop.find(tok->str) != altop.end()) { |
1809 | | - bool alt; |
1810 | | - if (tok->str == "not") { |
1811 | | - alt = isAlternativeUnaryOp(tok,tok->str); |
1812 | | - } else { |
1813 | | - alt = isAlternativeBinaryOp(tok,tok->str); |
1814 | | - } |
1815 | | - if (alt) |
1816 | | - continue; |
| 1801 | +static const char * const altopData[] = {"and","or","bitand","bitor","not","not_eq","xor"}; |
| 1802 | +static const std::set<std::string> altop(&altopData[0], &altopData[7]); |
| 1803 | +static void simplifyName(simplecpp::TokenList &expr) |
| 1804 | +{ |
| 1805 | + for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) { |
| 1806 | + if (tok->name) { |
| 1807 | + if (altop.find(tok->str) != altop.end()) { |
| 1808 | + bool alt; |
| 1809 | + if (tok->str == "not") { |
| 1810 | + alt = isAlternativeUnaryOp(tok,tok->str); |
| 1811 | + } else { |
| 1812 | + alt = isAlternativeBinaryOp(tok,tok->str); |
1817 | 1813 | } |
1818 | | - tok->setstr("0"); |
| 1814 | + if (alt) |
| 1815 | + continue; |
1819 | 1816 | } |
| 1817 | + tok->setstr("0"); |
1820 | 1818 | } |
1821 | 1819 | } |
| 1820 | +} |
1822 | 1821 |
|
1823 | | - void simplifyNumbers(simplecpp::TokenList &expr) |
1824 | | - { |
1825 | | - for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) { |
1826 | | - if (tok->str.size() == 1U) |
1827 | | - continue; |
1828 | | - if (tok->str.compare(0,2,"0x") == 0) |
1829 | | - tok->setstr(toString(stringToULL(tok->str))); |
1830 | | - else if (tok->str[0] == '\'') |
1831 | | - tok->setstr(toString(tok->str[1] & 0xffU)); |
1832 | | - } |
1833 | | - } |
1834 | | - |
1835 | | - long long evaluate(simplecpp::TokenList &expr, const std::map<std::string, std::size_t> &sizeOfType) |
1836 | | - { |
1837 | | - simplifySizeof(expr, sizeOfType); |
1838 | | - simplifyName(expr); |
1839 | | - simplifyNumbers(expr); |
1840 | | - expr.constFold(); |
1841 | | - // TODO: handle invalid expressions |
1842 | | - return expr.cfront() && expr.cfront() == expr.cback() && expr.cfront()->number ? stringToLL(expr.cfront()->str) : 0LL; |
| 1822 | +static void simplifyNumbers(simplecpp::TokenList &expr) |
| 1823 | +{ |
| 1824 | + for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) { |
| 1825 | + if (tok->str.size() == 1U) |
| 1826 | + continue; |
| 1827 | + if (tok->str.compare(0,2,"0x") == 0) |
| 1828 | + tok->setstr(toString(stringToULL(tok->str))); |
| 1829 | + else if (tok->str[0] == '\'') |
| 1830 | + tok->setstr(toString(tok->str[1] & 0xffU)); |
1843 | 1831 | } |
| 1832 | +} |
1844 | 1833 |
|
1845 | | - const simplecpp::Token *gotoNextLine(const simplecpp::Token *tok) |
1846 | | - { |
1847 | | - const unsigned int line = tok->location.line; |
1848 | | - const unsigned int file = tok->location.fileIndex; |
1849 | | - while (tok && tok->location.line == line && tok->location.fileIndex == file) |
1850 | | - tok = tok->next; |
1851 | | - return tok; |
1852 | | - } |
| 1834 | +static long long evaluate(simplecpp::TokenList &expr, const std::map<std::string, std::size_t> &sizeOfType) |
| 1835 | +{ |
| 1836 | + simplifySizeof(expr, sizeOfType); |
| 1837 | + simplifyName(expr); |
| 1838 | + simplifyNumbers(expr); |
| 1839 | + expr.constFold(); |
| 1840 | + // TODO: handle invalid expressions |
| 1841 | + return expr.cfront() && expr.cfront() == expr.cback() && expr.cfront()->number ? stringToLL(expr.cfront()->str) : 0LL; |
| 1842 | +} |
1853 | 1843 |
|
1854 | | - std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const std::string &sourcefile, const std::string &header, bool systemheader) |
1855 | | - { |
1856 | | - if (!systemheader) { |
1857 | | - if (sourcefile.find_first_of("\\/") != std::string::npos) { |
1858 | | - const std::string s = sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header; |
1859 | | - f.open(s.c_str()); |
1860 | | - if (f.is_open()) |
1861 | | - return simplecpp::simplifyPath(s); |
1862 | | - } else { |
1863 | | - f.open(header.c_str()); |
1864 | | - if (f.is_open()) |
1865 | | - return simplecpp::simplifyPath(header); |
1866 | | - } |
1867 | | - } |
| 1844 | +static const simplecpp::Token *gotoNextLine(const simplecpp::Token *tok) |
| 1845 | +{ |
| 1846 | + const unsigned int line = tok->location.line; |
| 1847 | + const unsigned int file = tok->location.fileIndex; |
| 1848 | + while (tok && tok->location.line == line && tok->location.fileIndex == file) |
| 1849 | + tok = tok->next; |
| 1850 | + return tok; |
| 1851 | +} |
1868 | 1852 |
|
1869 | | - for (std::list<std::string>::const_iterator it = dui.includePaths.begin(); it != dui.includePaths.end(); ++it) { |
1870 | | - std::string s = *it; |
1871 | | - if (!s.empty() && s[s.size()-1U]!='/' && s[s.size()-1U]!='\\') |
1872 | | - s += '/'; |
1873 | | - s += header; |
| 1853 | +static std::string openHeader(std::ifstream &f, const simplecpp::DUI &dui, const std::string &sourcefile, const std::string &header, bool systemheader) |
| 1854 | +{ |
| 1855 | + if (!systemheader) { |
| 1856 | + if (sourcefile.find_first_of("\\/") != std::string::npos) { |
| 1857 | + const std::string s = sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header; |
1874 | 1858 | f.open(s.c_str()); |
1875 | 1859 | if (f.is_open()) |
1876 | 1860 | return simplecpp::simplifyPath(s); |
| 1861 | + } else { |
| 1862 | + f.open(header.c_str()); |
| 1863 | + if (f.is_open()) |
| 1864 | + return simplecpp::simplifyPath(header); |
1877 | 1865 | } |
| 1866 | + } |
1878 | 1867 |
|
1879 | | - return ""; |
| 1868 | + for (std::list<std::string>::const_iterator it = dui.includePaths.begin(); it != dui.includePaths.end(); ++it) { |
| 1869 | + std::string s = *it; |
| 1870 | + if (!s.empty() && s[s.size()-1U]!='/' && s[s.size()-1U]!='\\') |
| 1871 | + s += '/'; |
| 1872 | + s += header; |
| 1873 | + f.open(s.c_str()); |
| 1874 | + if (f.is_open()) |
| 1875 | + return simplecpp::simplifyPath(s); |
1880 | 1876 | } |
1881 | 1877 |
|
1882 | | - std::string getFileName(const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader) |
1883 | | - { |
1884 | | - if (!systemheader) { |
1885 | | - if (sourcefile.find_first_of("\\/") != std::string::npos) { |
1886 | | - const std::string s(simplecpp::simplifyPath(sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header)); |
1887 | | - if (filedata.find(s) != filedata.end()) |
1888 | | - return s; |
1889 | | - } else { |
1890 | | - std::string s = simplecpp::simplifyPath(header); |
1891 | | - if (filedata.find(s) != filedata.end()) |
1892 | | - return s; |
1893 | | - } |
1894 | | - } |
| 1878 | + return ""; |
| 1879 | +} |
1895 | 1880 |
|
1896 | | - for (std::list<std::string>::const_iterator it = dui.includePaths.begin(); it != dui.includePaths.end(); ++it) { |
1897 | | - std::string s = *it; |
1898 | | - if (!s.empty() && s[s.size()-1U]!='/' && s[s.size()-1U]!='\\') |
1899 | | - s += '/'; |
1900 | | - s += header; |
1901 | | - s = simplecpp::simplifyPath(s); |
| 1881 | +static std::string getFileName(const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader) |
| 1882 | +{ |
| 1883 | + if (!systemheader) { |
| 1884 | + if (sourcefile.find_first_of("\\/") != std::string::npos) { |
| 1885 | + const std::string s(simplecpp::simplifyPath(sourcefile.substr(0, sourcefile.find_last_of("\\/") + 1U) + header)); |
| 1886 | + if (filedata.find(s) != filedata.end()) |
| 1887 | + return s; |
| 1888 | + } else { |
| 1889 | + std::string s = simplecpp::simplifyPath(header); |
1902 | 1890 | if (filedata.find(s) != filedata.end()) |
1903 | 1891 | return s; |
1904 | 1892 | } |
1905 | | - |
1906 | | - return ""; |
1907 | 1893 | } |
1908 | 1894 |
|
1909 | | - bool hasFile(const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader) |
1910 | | - { |
1911 | | - return !getFileName(filedata, sourcefile, header, dui, systemheader).empty(); |
| 1895 | + for (std::list<std::string>::const_iterator it = dui.includePaths.begin(); it != dui.includePaths.end(); ++it) { |
| 1896 | + std::string s = *it; |
| 1897 | + if (!s.empty() && s[s.size()-1U]!='/' && s[s.size()-1U]!='\\') |
| 1898 | + s += '/'; |
| 1899 | + s += header; |
| 1900 | + s = simplecpp::simplifyPath(s); |
| 1901 | + if (filedata.find(s) != filedata.end()) |
| 1902 | + return s; |
1912 | 1903 | } |
| 1904 | + |
| 1905 | + return ""; |
| 1906 | +} |
| 1907 | + |
| 1908 | +static bool hasFile(const std::map<std::string, simplecpp::TokenList *> &filedata, const std::string &sourcefile, const std::string &header, const simplecpp::DUI &dui, bool systemheader) |
| 1909 | +{ |
| 1910 | + return !getFileName(filedata, sourcefile, header, dui, systemheader).empty(); |
1913 | 1911 | } |
1914 | 1912 |
|
1915 | 1913 | std::map<std::string, simplecpp::TokenList*> simplecpp::load(const simplecpp::TokenList &rawtokens, std::vector<std::string> &fileNumbers, const simplecpp::DUI &dui, simplecpp::OutputList *outputList) |
|
0 commit comments