MCPcopy Create free account
hub / github.com/OSGeo/gdal / CPLLexicallyNormalize

Function CPLLexicallyNormalize

port/cpl_path.cpp:1825–1906  ·  view source on GitHub ↗

* Return a path where "/./" or "/../" sequences are removed. * * No filesystem access is done. * * @param svPath Input path * @param sep1 Path separator (typically slash or backslash) * @param sep2 Secondary path separator (typically slash or backslash), or NUL * @return compacted path * * @since GDAL 3.13 */

Source from the content-addressed store, hash-verified

1823 * @since GDAL 3.13
1824 */
1825std::string CPLLexicallyNormalize(std::string_view svPath, char sep1, char sep2)
1826{
1827 struct Token
1828 {
1829 size_t iStart = 0; // index of start of token with svPath
1830 size_t nLen = 0; // length of token (excluding ending separator)
1831 char chSep = 0; // separator at end of token, or 0 if there is none
1832 };
1833
1834 std::vector<Token> tokens;
1835
1836 const auto CompactTokens = [&tokens, &svPath]()
1837 {
1838 Token &t = tokens.back();
1839 if (t.nLen == 1 && svPath[t.iStart] == '.')
1840 {
1841 tokens.pop_back();
1842 }
1843 else if (t.nLen == 2 && svPath[t.iStart] == '.' &&
1844 svPath[t.iStart + 1] == '.')
1845 {
1846 if (tokens.size() >= 2)
1847 tokens.resize(tokens.size() - 2);
1848 }
1849 };
1850
1851 bool lastCharIsSep = false;
1852 for (size_t i = 0; i < svPath.size(); ++i)
1853 {
1854 const char c = svPath[i];
1855 if (c == sep1 || c == sep2)
1856 {
1857 if (!lastCharIsSep)
1858 {
1859 if (tokens.empty())
1860 {
1861 Token t;
1862 t.chSep = c;
1863 tokens.push_back(t);
1864 }
1865 else
1866 {
1867 Token &t = tokens.back();
1868 t.chSep = c;
1869 CompactTokens();
1870 }
1871 lastCharIsSep = true;
1872 }
1873 }
1874 else
1875 {
1876 if (tokens.empty() || lastCharIsSep)
1877 {
1878 Token t;
1879 t.iStart = i;
1880 t.nLen = 1;
1881 tokens.push_back(t);
1882 }

Callers 2

TEST_FFunction · 0.85

Calls 4

sizeMethod · 0.45
resizeMethod · 0.45
emptyMethod · 0.45
push_backMethod · 0.45

Tested by 1

TEST_FFunction · 0.68