* strtokx2 * * strtokx2 is a replica of psql's strtokx (bin/psql/stringutils.c), fitted * to be used in the backend for the same purpose - parsing an sql string of * literals. Information follows (right now identical to strtokx, except for * a small hack - see below comment about MPP-6698): * * Replacement for strtok() (a.k.a. poor man's flex) * * Splits a string into tokens, returning on
| 98 | * since you might lose data. |
| 99 | */ |
| 100 | extern char * |
| 101 | strtokx2(const char *s, |
| 102 | const char *whitespace, |
| 103 | const char *delim, |
| 104 | const char *quote, |
| 105 | char escape, |
| 106 | bool e_strings, |
| 107 | bool del_quotes, |
| 108 | int encoding) |
| 109 | { |
| 110 | static char *storage = NULL;/* store the local copy of the users string |
| 111 | * here */ |
| 112 | static char *string = NULL; /* pointer into storage where to continue on |
| 113 | * next call */ |
| 114 | |
| 115 | /* variously abused variables: */ |
| 116 | unsigned int offset; |
| 117 | char *start; |
| 118 | char *p; |
| 119 | |
| 120 | if (s) |
| 121 | { |
| 122 | /* |
| 123 | * We may need extra space to insert delimiter nulls for adjacent |
| 124 | * tokens. 2X the space is a gross overestimate, but it's unlikely |
| 125 | * that this code will be used on huge strings anyway. |
| 126 | */ |
| 127 | storage = palloc(2 * strlen(s) + 1); |
| 128 | strcpy(storage, s); |
| 129 | string = storage; |
| 130 | } |
| 131 | |
| 132 | if (!storage) |
| 133 | return NULL; |
| 134 | |
| 135 | /* skip leading whitespace */ |
| 136 | offset = strspn(string, whitespace); |
| 137 | start = &string[offset]; |
| 138 | |
| 139 | /* end of string reached? */ |
| 140 | if (*start == '\0') |
| 141 | { |
| 142 | /* technically we don't need to free here, but we're nice */ |
| 143 | pfree(storage); |
| 144 | storage = NULL; |
| 145 | string = NULL; |
| 146 | return NULL; |
| 147 | } |
| 148 | |
| 149 | /* test if delimiter character */ |
| 150 | if (delim && strchr(delim, *start)) |
| 151 | { |
| 152 | /* |
| 153 | * If not at end of string, we need to insert a null to terminate the |
| 154 | * returned token. We can just overwrite the next character if it |
| 155 | * happens to be in the whitespace set ... otherwise move over the |
| 156 | * rest of the string to make room. (This is why we allocated extra |
| 157 | * space above). |
no test coverage detected