| 1751 | }; |
| 1752 | |
| 1753 | class FileInputStreamReader : public InputStreamReader { |
| 1754 | private: |
| 1755 | std::FILE *file; |
| 1756 | std::string name; |
| 1757 | int line; |
| 1758 | std::vector<int> undoChars; |
| 1759 | std::vector<int> readChars; |
| 1760 | std::vector<int> undoReadChars; |
| 1761 | |
| 1762 | inline int postprocessGetc(int getcResult) { |
| 1763 | if (getcResult != EOF) |
| 1764 | return getcResult; |
| 1765 | else |
| 1766 | return EOFC; |
| 1767 | } |
| 1768 | |
| 1769 | int getc(FILE *file) { |
| 1770 | int c; |
| 1771 | int rc; |
| 1772 | |
| 1773 | if (undoChars.empty()) { |
| 1774 | c = rc = ::getc(file); |
| 1775 | } else { |
| 1776 | c = undoChars.back(); |
| 1777 | undoChars.pop_back(); |
| 1778 | rc = undoReadChars.back(); |
| 1779 | undoReadChars.pop_back(); |
| 1780 | } |
| 1781 | |
| 1782 | if (c == LF) |
| 1783 | line++; |
| 1784 | |
| 1785 | readChars.push_back(rc); |
| 1786 | return c; |
| 1787 | } |
| 1788 | |
| 1789 | int ungetc(int c/*, FILE* file*/) { |
| 1790 | if (!readChars.empty()) { |
| 1791 | undoReadChars.push_back(readChars.back()); |
| 1792 | readChars.pop_back(); |
| 1793 | } |
| 1794 | if (c == LF) |
| 1795 | line--; |
| 1796 | undoChars.push_back(c); |
| 1797 | return c; |
| 1798 | } |
| 1799 | |
| 1800 | public: |
| 1801 | FileInputStreamReader(std::FILE *file, const std::string &name) : file(file), name(name), line(1) { |
| 1802 | // No operations. |
| 1803 | } |
| 1804 | |
| 1805 | void setTestCase(int testCase) { |
| 1806 | if (testCase < 0 || testCase > __TESTLIB_MAX_TEST_CASE) |
| 1807 | __testlib_fail(format("testCase expected fit in [1,%d], but %d doesn't", __TESTLIB_MAX_TEST_CASE, testCase)); |
| 1808 | readChars.push_back(testCase + 256); |
| 1809 | } |
| 1810 |
nothing calls this directly
no outgoing calls
no test coverage detected