diff options
Diffstat (limited to 'src/bin/psql/stringutils.c')
-rw-r--r-- | src/bin/psql/stringutils.c | 249 |
1 files changed, 133 insertions, 116 deletions
diff --git a/src/bin/psql/stringutils.c b/src/bin/psql/stringutils.c index c495fd49660..b4f5be926bf 100644 --- a/src/bin/psql/stringutils.c +++ b/src/bin/psql/stringutils.c @@ -2,11 +2,13 @@ #include <c.h> #include "stringutils.h" -//#include <ctype.h> +// +#include <ctype.h> #include <stdlib.h> #include <string.h> #include <assert.h> -//#include <stdio.h> +// +#include <stdio.h> #include <postgres.h> #ifndef HAVE_STRDUP @@ -17,118 +19,130 @@ static void -unescape_quotes(char *source, char quote, char escape); + unescape_quotes(char *source, char quote, char escape); /* * Replacement for strtok() (a.k.a. poor man's flex) * * The calling convention is similar to that of strtok. - * s - string to parse, if NULL continue parsing the last string - * delim - set of characters that delimit tokens (usually whitespace) - * quote - set of characters that quote stuff, they're not part of the token - * escape - character than can quote quotes + * s - string to parse, if NULL continue parsing the last string + * delim - set of characters that delimit tokens (usually whitespace) + * quote - set of characters that quote stuff, they're not part of the token + * escape - character than can quote quotes * was_quoted - if not NULL, stores the quoting character if any was encountered - * token_pos - if not NULL, receives a count to the start of the token in the - * parsed string + * token_pos - if not NULL, receives a count to the start of the token in the + * parsed string * * Note that the string s is _not_ overwritten in this implementation. */ -char * strtokx(const char *s, - const char *delim, - const char *quote, - char escape, - char * was_quoted, - unsigned int * token_pos) +char * +strtokx(const char *s, + const char *delim, + const char *quote, + char escape, + char *was_quoted, + unsigned int *token_pos) { - static char * storage = NULL; /* store the local copy of the users string here */ - static char * string = NULL; /* pointer into storage where to continue on next call */ - /* variously abused variables: */ - unsigned int offset; - char * start; - char *cp = NULL; - - if (s) { - free(storage); - storage = strdup(s); - string = storage; - } - - if (!storage) - return NULL; - - /* skip leading "whitespace" */ - offset = strspn(string, delim); - - /* end of string reached */ - if (string[offset] == '\0') { - /* technically we don't need to free here, but we're nice */ - free(storage); - storage = NULL; - string = NULL; - return NULL; - } - - /* test if quoting character */ - if (quote) - cp = strchr(quote, string[offset]); - - if (cp) { - /* okay, we have a quoting character, now scan for the closer */ - char *p; - start = &string[offset+1]; + static char *storage = NULL;/* store the local copy of the users + * string here */ + static char *string = NULL; /* pointer into storage where to continue + * on next call */ + + /* variously abused variables: */ + unsigned int offset; + char *start; + char *cp = NULL; + + if (s) + { + free(storage); + storage = strdup(s); + string = storage; + } - if (token_pos) - *token_pos = start - storage; + if (!storage) + return NULL; + + /* skip leading "whitespace" */ + offset = strspn(string, delim); + + /* end of string reached */ + if (string[offset] == '\0') + { + /* technically we don't need to free here, but we're nice */ + free(storage); + storage = NULL; + string = NULL; + return NULL; + } - for(p = start; - *p && (*p != *cp || *(p-1) == escape) ; + /* test if quoting character */ + if (quote) + cp = strchr(quote, string[offset]); + + if (cp) + { + /* okay, we have a quoting character, now scan for the closer */ + char *p; + + start = &string[offset + 1]; + + if (token_pos) + *token_pos = start - storage; + + for (p = start; + *p && (*p != *cp || *(p - 1) == escape); #ifdef MULTIBYTE - p += PQmblen(p) + p += PQmblen(p) #else - p++ + p++ #endif - ); - - /* not yet end of string? */ - if (*p != '\0') { - *p = '\0'; - string = p + 1; - if (was_quoted) - *was_quoted = *cp; - unescape_quotes (start, *cp, escape); - return start; + ); + + /* not yet end of string? */ + if (*p != '\0') + { + *p = '\0'; + string = p + 1; + if (was_quoted) + *was_quoted = *cp; + unescape_quotes(start, *cp, escape); + return start; + } + else + { + if (was_quoted) + *was_quoted = *cp; + string = p; + + unescape_quotes(start, *cp, escape); + return start; + } } - else { - if (was_quoted) - *was_quoted = *cp; - string = p; - unescape_quotes (start, *cp, escape); - return start; - } - } + /* otherwise no quoting character. scan till next delimiter */ + start = &string[offset]; - /* otherwise no quoting character. scan till next delimiter */ - start = &string[offset]; - - if (token_pos) - *token_pos = start - storage; + if (token_pos) + *token_pos = start - storage; - offset = strcspn(start, delim); - if (was_quoted) - *was_quoted = 0; + offset = strcspn(start, delim); + if (was_quoted) + *was_quoted = 0; - if (start[offset] != '\0') { - start[offset] = '\0'; - string = &start[offset]+1; + if (start[offset] != '\0') + { + start[offset] = '\0'; + string = &start[offset] + 1; - return start; - } - else { - string = &start[offset]; - return start; - } + return start; + } + else + { + string = &start[offset]; + return start; + } } @@ -142,38 +156,41 @@ char * strtokx(const char *s, static void unescape_quotes(char *source, char quote, char escape) { - char *p; - char *destination, *tmp; + char *p; + char *destination, + *tmp; #ifdef USE_ASSERT_CHECKING - assert(source); + assert(source); #endif - destination = (char *) calloc(1, strlen(source)+1); - if (!destination) { - perror("calloc"); - exit(EXIT_FAILURE); - } + destination = (char *) calloc(1, strlen(source) + 1); + if (!destination) + { + perror("calloc"); + exit(EXIT_FAILURE); + } - tmp = destination; + tmp = destination; - for (p = source; *p; p++) - { - char c; + for (p = source; *p; p++) + { + char c; - if (*p == escape && *(p+1) && quote == *(p+1)) { - c = *(p+1); - p++; - } - else - c = *p; + if (*p == escape && *(p + 1) && quote == *(p + 1)) + { + c = *(p + 1); + p++; + } + else + c = *p; - *tmp = c; - tmp ++; - } + *tmp = c; + tmp++; + } - /* Terminating null character */ - *tmp = '\0'; + /* Terminating null character */ + *tmp = '\0'; - strcpy(source, destination); + strcpy(source, destination); } |