| 1804 | |
| 1805 | |
| 1806 | char* XMLElement::ParseAttributes(char* p, int* curLineNumPtr) |
| 1807 | { |
| 1808 | const char* start = p; |
| 1809 | XMLAttribute* prevAttribute = 0; |
| 1810 | |
| 1811 | // Read the attributes. |
| 1812 | while (p) { |
| 1813 | p = XMLUtil::SkipWhiteSpace(p, curLineNumPtr); |
| 1814 | if (!(*p)) { |
| 1815 | _document->SetError(XML_ERROR_PARSING_ELEMENT, start, Name(), _parseLineNum); |
| 1816 | return 0; |
| 1817 | } |
| 1818 | |
| 1819 | // attribute. |
| 1820 | if (XMLUtil::IsNameStartChar(*p)) { |
| 1821 | XMLAttribute* attrib = CreateAttribute(); |
| 1822 | TIXMLASSERT(attrib); |
| 1823 | attrib->_parseLineNum = _document->_parseCurLineNum; |
| 1824 | |
| 1825 | int attrLineNum = attrib->_parseLineNum; |
| 1826 | |
| 1827 | p = attrib->ParseDeep(p, _document->ProcessEntities(), curLineNumPtr); |
| 1828 | if (!p || Attribute(attrib->Name())) { |
| 1829 | DeleteAttribute(attrib); |
| 1830 | _document->SetError(XML_ERROR_PARSING_ATTRIBUTE, start, p, attrLineNum); |
| 1831 | return 0; |
| 1832 | } |
| 1833 | // There is a minor bug here: if the attribute in the source xml |
| 1834 | // document is duplicated, it will not be detected and the |
| 1835 | // attribute will be doubly added. However, tracking the 'prevAttribute' |
| 1836 | // avoids re-scanning the attribute list. Preferring performance for |
| 1837 | // now, may reconsider in the future. |
| 1838 | if (prevAttribute) { |
| 1839 | TIXMLASSERT(prevAttribute->_next == 0); |
| 1840 | prevAttribute->_next = attrib; |
| 1841 | } |
| 1842 | else { |
| 1843 | TIXMLASSERT(_rootAttribute == 0); |
| 1844 | _rootAttribute = attrib; |
| 1845 | } |
| 1846 | prevAttribute = attrib; |
| 1847 | } |
| 1848 | // end of the tag |
| 1849 | else if (*p == '>') { |
| 1850 | ++p; |
| 1851 | break; |
| 1852 | } |
| 1853 | // end of the tag |
| 1854 | else if (*p == '/' && *(p + 1) == '>') { |
| 1855 | _closingType = CLOSED; |
| 1856 | return p + 2; // done; sealed element. |
| 1857 | } |
| 1858 | else { |
| 1859 | _document->SetError(XML_ERROR_PARSING_ELEMENT, start, p, _parseLineNum); |
| 1860 | return 0; |
| 1861 | } |
| 1862 | } |
| 1863 | return p; |
nothing calls this directly
no test coverage detected