| 815 | */ |
| 816 | |
| 817 | char **CSLTokenizeString2(const char *pszString, const char *pszDelimiters, |
| 818 | int nCSLTFlags) |
| 819 | { |
| 820 | if (pszString == nullptr) |
| 821 | return static_cast<char **>(CPLCalloc(sizeof(char *), 1)); |
| 822 | |
| 823 | CPLStringList oRetList; |
| 824 | const bool bHonourStrings = (nCSLTFlags & CSLT_HONOURSTRINGS) != 0; |
| 825 | const bool bAllowEmptyTokens = (nCSLTFlags & CSLT_ALLOWEMPTYTOKENS) != 0; |
| 826 | const bool bStripLeadSpaces = (nCSLTFlags & CSLT_STRIPLEADSPACES) != 0; |
| 827 | const bool bStripEndSpaces = (nCSLTFlags & CSLT_STRIPENDSPACES) != 0; |
| 828 | |
| 829 | char *pszToken = static_cast<char *>(CPLCalloc(10, 1)); |
| 830 | size_t nTokenMax = 10; |
| 831 | |
| 832 | while (*pszString != '\0') |
| 833 | { |
| 834 | bool bInString = false; |
| 835 | bool bStartString = true; |
| 836 | size_t nTokenLen = 0; |
| 837 | |
| 838 | // Try to find the next delimiter, marking end of token. |
| 839 | for (; *pszString != '\0'; ++pszString) |
| 840 | { |
| 841 | // Extend token buffer if we are running close to its end. |
| 842 | if (nTokenLen >= nTokenMax - 3) |
| 843 | { |
| 844 | if (nTokenMax > std::numeric_limits<size_t>::max() / 2) |
| 845 | { |
| 846 | CPLFree(pszToken); |
| 847 | return static_cast<char **>(CPLCalloc(sizeof(char *), 1)); |
| 848 | } |
| 849 | nTokenMax = nTokenMax * 2; |
| 850 | char *pszNewToken = static_cast<char *>( |
| 851 | VSI_REALLOC_VERBOSE(pszToken, nTokenMax)); |
| 852 | if (pszNewToken == nullptr) |
| 853 | { |
| 854 | CPLFree(pszToken); |
| 855 | return static_cast<char **>(CPLCalloc(sizeof(char *), 1)); |
| 856 | } |
| 857 | pszToken = pszNewToken; |
| 858 | } |
| 859 | |
| 860 | // End if this is a delimiter skip it and break. |
| 861 | if (!bInString && strchr(pszDelimiters, *pszString) != nullptr) |
| 862 | { |
| 863 | ++pszString; |
| 864 | break; |
| 865 | } |
| 866 | |
| 867 | // If this is a quote, and we are honouring constant |
| 868 | // strings, then process the constant strings, with out delim |
| 869 | // but don't copy over the quotes. |
| 870 | if (bHonourStrings && *pszString == '"') |
| 871 | { |
| 872 | if (nCSLTFlags & CSLT_PRESERVEQUOTES) |
| 873 | { |
| 874 | pszToken[nTokenLen] = *pszString; |