1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-14 18:42:34 +03:00

Major psql overhaul by Peter Eisentraut.

This commit is contained in:
Bruce Momjian
1999-11-04 21:56:02 +00:00
parent 2ea3b6d63a
commit a45195a191
30 changed files with 7026 additions and 152 deletions

View File

@ -1,119 +1,179 @@
/*-------------------------------------------------------------------------
*
* stringutils.c
* simple string manipulation routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/psql/stringutils.c,v 1.17 1999/07/17 20:18:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <ctype.h>
#include "postgres.h"
#ifndef HAVE_STRDUP
#include "strdup.h"
#endif
#include <config.h>
#include <c.h>
#include "stringutils.h"
/* all routines assume null-terminated strings! */
//#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
//#include <stdio.h>
/* The following routines remove whitespaces from the left, right
and both sides of a string */
/* MODIFIES the string passed in and returns the head of it */
#include <postgres.h>
#ifndef HAVE_STRDUP
#include <strdup.h>
#endif
#include <libpq-fe.h>
#ifdef NOT_USED
static char *
leftTrim(char *s)
static void
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
* 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
*
* 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 *s2 = s;
int shift = 0;
int j = 0;
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;
while (isspace(*s))
{
s++;
shift++;
}
if (shift > 0)
{
while ((s2[j] = s2[j + shift]) != '\0')
j++;
}
if (s) {
free(storage);
storage = strdup(s);
string = storage;
}
return s2;
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];
if (token_pos)
*token_pos = start - storage;
for(p = start;
*p && (*p != *cp || *(p-1) == escape) ;
#ifdef MULTIBYTE
p += PQmblen(p)
#else
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;
}
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];
if (token_pos)
*token_pos = start - storage;
offset = strcspn(start, delim);
if (was_quoted)
*was_quoted = 0;
if (start[offset] != '\0') {
start[offset] = '\0';
string = &start[offset]+1;
return start;
}
else {
string = &start[offset];
return start;
}
}
/*
* unescape_quotes
*
* Resolves escaped quotes. Used by strtokx above.
*/
static void
unescape_quotes(char *source, char quote, char escape)
{
char *p;
char *destination, *tmp;
#ifdef USE_ASSERT_CHECKING
assert(source);
#endif
char *
rightTrim(char *s)
{
char *sEnd,
*bsEnd;
bool in_bs = false;
destination = (char *) calloc(1, strlen(source)+1);
if (!destination) {
perror("calloc");
exit(EXIT_FAILURE);
}
sEnd = s + strlen(s) - 1;
while (sEnd >= s && isspace(*sEnd))
sEnd--;
bsEnd = sEnd;
while (bsEnd >= s && *bsEnd == '\\')
{
in_bs = (in_bs == false);
bsEnd--;
tmp = destination;
for (p = source; *p; p++)
{
char c;
if (*p == escape && *(p+1) && quote == *(p+1)) {
c = *(p+1);
p++;
}
if (in_bs && *sEnd)
sEnd++;
if (sEnd < s)
s[0] = '\0';
else
s[sEnd - s + 1] = '\0';
return s;
c = *p;
*tmp = c;
tmp ++;
}
/* Terminating null character */
*tmp = '\0';
strcpy(source, destination);
}
#ifdef NOT_USED
static char *
doubleTrim(char *s)
{
strcpy(s, leftTrim(rightTrim(s)));
return s;
}
#endif
#ifdef STRINGUTILS_TEST
void
testStringUtils()
{
static char *tests[] = {" goodbye \n", /* space on both ends */
"hello world", /* no spaces to trim */
"", /* empty string */
"a", /* string with one char */
" ", /* string with one whitespace */
NULL_STR};
int i = 0;
while (tests[i] != NULL_STR)
{
char *t;
t = strdup(tests[i]);
printf("leftTrim(%s) = ", t);
printf("%sEND\n", leftTrim(t));
t = strdup(tests[i]);
printf("rightTrim(%s) = ", t);
printf("%sEND\n", rightTrim(t));
t = strdup(tests[i]);
printf("doubleTrim(%s) = ", t);
printf("%sEND\n", doubleTrim(t));
i++;
}
}
#endif