1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

Update of contrib stuff from massimo.

This commit is contained in:
Bruce Momjian
1997-11-05 21:38:25 +00:00
parent 5aaf00f3f3
commit 951986c550
33 changed files with 2547 additions and 578 deletions

62
contrib/string/Makefile Normal file
View File

@ -0,0 +1,62 @@
#-------------------------------------------------------------------------
#
# Makefile--
# Makefile for new string I/O functions.
#
#-------------------------------------------------------------------------
PGDIR = ../..
SRCDIR = $(PGDIR)/src
include $(SRCDIR)/Makefile.global
INCLUDE_OPT = -I ./ \
-I $(SRCDIR)/ \
-I $(SRCDIR)/include \
-I $(SRCDIR)/port/$(PORTNAME)
CFLAGS += $(INCLUDE_OPT)
ifeq ($(PORTNAME), linux)
ifdef LINUX_ELF
ifeq ($(CC), gcc)
CFLAGS += -fPIC
endif
endif
endif
ifeq ($(PORTNAME), i386_solaris)
CFLAGS+= -fPIC
endif
MODNAME = string_io
MODULE = $(MODNAME)$(DLSUFFIX)
all: module sql
module: $(MODULE)
sql: $(MODNAME).sql
install: $(MODULE)
cp -p $(MODULE) $(LIBDIR)
cd $(LIBDIR); strip $(MODULE)
%.sql: %.sql.in
sed "s|MODULE_PATHNAME|$(LIBDIR)/$(MODULE)|" < $< > $@
.SUFFIXES: $(DLSUFFIX)
%$(DLSUFFIX): %.c
cc $(CFLAGS) -shared -o $@ $<
depend dep:
$(CC) -MM $(INCLUDE_OPT) *.c >depend
clean:
rm -f $(MODULE) $(MODNAME).sql
ifeq (depend,$(wildcard depend))
include depend
endif

View File

@ -14,17 +14,19 @@
#include "utils/palloc.h"
#include "utils/builtins.h"
#include "string_io.h"
/* define this if you want to see iso-8859 characters */
#define ISO8859
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define VALUE(char) ((char) - '0')
#define DIGIT(val) ((val) + '0')
#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define VALUE(char) ((char) - '0')
#define DIGIT(val) ((val) + '0')
#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7'))
#ifndef ISO8859
#define NOTPRINTABLE(c) (!isprint(c))
#define NOTPRINTABLE(c) (!isprint(c))
#else
#define NOTPRINTABLE(c) (!isprint(c) && ((c) < 0xa0))
#define NOTPRINTABLE(c) (!isprint(c) && ((c) < 0xa0))
#endif
/*
@ -36,129 +38,115 @@
* The function is used by output methods of various string types.
*
* Arguments:
* data - input data (can be NULL)
* size - optional size of data. A negative value indicates
* that data is a null terminated string.
* data - input data (can be NULL)
* size - optional size of data. A negative value indicates
* that data is a null terminated string.
*
* Returns:
* a pointer to a new string containing the printable
* representation of data.
* a pointer to a new string containing the printable
* representation of data.
*/
char *
char *
string_output(char *data, int size)
{
register unsigned char c,
*p,
*r,
*result;
register int l,
len;
register unsigned char c, *p, *r, *result;
register int l, len;
if (data == NULL)
{
result = (char *) palloc(2);
result[0] = '-';
result[1] = '\0';
return (result);
if (data == NULL) {
result = (char *) palloc(2);
result[0] = '-';
result[1] = '\0';
return (result);
}
if (size < 0) {
size = strlen(data);
}
/* adjust string length for escapes */
len = size;
for (p=data,l=size; l>0; p++,l--) {
switch (*p) {
case '\\':
case '"' :
case '{':
case '}':
case '\b':
case '\f':
case '\n':
case '\r':
case '\t':
case '\v':
len++;
break;
default:
if (NOTPRINTABLE(*p)) {
len += 3;
}
}
}
len++;
if (size < 0)
{
size = strlen(data);
result = (char *) palloc(len);
for (p=data,r=result,l=size; (l > 0) && (c = *p); p++,l--) {
switch (c) {
case '\\':
case '"' :
case '{':
case '}':
*r++ = '\\';
*r++ = c;
break;
case '\b':
*r++ = '\\';
*r++ = 'b';
break;
case '\f':
*r++ = '\\';
*r++ = 'f';
break;
case '\n':
*r++ = '\\';
*r++ = 'n';
break;
case '\r':
*r++ = '\\';
*r++ = 'r';
break;
case '\t':
*r++ = '\\';
*r++ = 't';
break;
case '\v':
*r++ = '\\';
*r++ = 'v';
break;
default:
if (NOTPRINTABLE(c)) {
*r = '\\';
r += 3;
*r-- = DIGIT(c & 07);
c >>= 3;
*r-- = DIGIT(c & 07);
c >>= 3;
*r = DIGIT(c & 03);
r += 3;
} else {
*r++ = c;
}
}
}
*r = '\0';
/* adjust string length for escapes */
len = size;
for (p = data, l = size; l > 0; p++, l--)
{
switch (*p)
{
case '\\':
case '"':
case '{':
case '}':
case '\b':
case '\f':
case '\n':
case '\r':
case '\t':
case '\v':
len++;
break;
default:
if (NOTPRINTABLE(*p))
{
len += 3;
}
}
}
len++;
result = (char *) palloc(len);
for (p = data, r = result, l = size; (l > 0) && (c = *p); p++, l--)
{
switch (c)
{
case '\\':
case '"':
case '{':
case '}':
*r++ = '\\';
*r++ = c;
break;
case '\b':
*r++ = '\\';
*r++ = 'b';
break;
case '\f':
*r++ = '\\';
*r++ = 'f';
break;
case '\n':
*r++ = '\\';
*r++ = 'n';
break;
case '\r':
*r++ = '\\';
*r++ = 'r';
break;
case '\t':
*r++ = '\\';
*r++ = 't';
break;
case '\v':
*r++ = '\\';
*r++ = 'v';
break;
default:
if (NOTPRINTABLE(c))
{
*r = '\\';
r += 3;
*r-- = DIGIT(c & 07);
c >>= 3;
*r-- = DIGIT(c & 07);
c >>= 3;
*r = DIGIT(c & 03);
r += 3;
}
else
{
*r++ = c;
}
}
}
*r = '\0';
return ((char *) result);
return((char *) result);
}
/*
* string_input() --
*
* This function accepts a C string in input and copies it into a new
* This function accepts a C string in input and copies it into a new
* object allocated with palloc() translating all escape sequences.
* An optional header can be allocatd before the string, for example
* to hold the length of a varlena object.
@ -167,231 +155,211 @@ string_output(char *data, int size)
* receive strings in internal form.
*
* Arguments:
* str - input string possibly with escapes
* size - the required size of new data. A value of 0
* indicates a variable size string, while a
* negative value indicates a variable size string
* of size not greater than this absolute value.
* hdrsize - size of an optional header to be allocated before
* the data. It must then be filled by the caller.
* rtn_size - an optional pointer to an int variable where the
* size of the new string is stored back.
* str - input string possibly with escapes
* size - the required size of new data. A value of 0
* indicates a variable size string, while a
* negative value indicates a variable size string
* of size not greater than this absolute value.
* hdrsize - size of an optional header to be allocated before
* the data. It must then be filled by the caller.
* rtn_size - an optional pointer to an int variable where the
* size of the new string is stored back.
*
* Returns:
* a pointer to the new string or the header.
* a pointer to the new string or the header.
*/
char *
char *
string_input(char *str, int size, int hdrsize, int *rtn_size)
{
register unsigned char *p,
*r;
unsigned char *result;
int len;
register unsigned char *p, *r;
unsigned char *result;
int len;
if ((str == NULL) || (hdrsize < 0))
{
return (char *) NULL;
}
if ((str == NULL) || (hdrsize < 0)) {
return (char *) NULL;
}
/* Compute result size */
len = strlen(str);
for (p = str; *p;)
{
if (*p++ == '\\')
{
if (ISOCTAL(*p))
{
if (ISOCTAL(*(p + 1)))
{
p++;
len--;
}
if (ISOCTAL(*(p + 1)))
{
p++;
len--;
}
}
if (*p)
p++;
len--;
/* Compute result size */
len = strlen(str);
for (p=str; *p; ) {
if (*p++ == '\\') {
if (ISOCTAL(*p)) {
if (ISOCTAL(*(p+1))) {
p++;
len--;
}
}
/* result has variable length */
if (size == 0)
{
size = len + 1;
}
else
/* result has variable length with maximum size */
if (size < 0)
{
size = MIN(len, -size) + 1;
}
result = (char *) palloc(hdrsize + size);
memset(result, 0, hdrsize + size);
if (rtn_size)
{
*rtn_size = size;
}
r = result + hdrsize;
for (p = str; *p;)
{
register unsigned char c;
if ((c = *p++) == '\\')
{
switch (c = *p++)
{
case '\0':
p--;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
c = VALUE(c);
if (isdigit(*p))
{
c = (c << 3) + VALUE(*p++);
}
if (isdigit(*p))
{
c = (c << 3) + VALUE(*p++);
}
*r++ = c;
break;
case 'b':
*r++ = '\b';
break;
case 'f':
*r++ = '\f';
break;
case 'n':
*r++ = '\n';
break;
case 'r':
*r++ = '\r';
break;
case 't':
*r++ = '\t';
break;
case 'v':
*r++ = '\v';
break;
default:
*r++ = c;
}
}
else
{
*r++ = c;
if (ISOCTAL(*(p+1))) {
p++;
len--;
}
}
if (*p) p++;
len--;
}
}
return ((char *) result);
/* result has variable length */
if (size == 0) {
size = len+1;
} else
/* result has variable length with maximum size */
if (size < 0) {
size = MIN(len, - size)+1;
}
result = (char *) palloc(hdrsize+size);
memset(result, 0, hdrsize+size);
if (rtn_size) {
*rtn_size = size;
}
r = result + hdrsize;
for (p=str; *p; ) {
register unsigned char c;
if ((c = *p++) == '\\') {
switch (c = *p++) {
case '\0':
p--;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
c = VALUE(c);
if (isdigit(*p)) {
c = (c<<3) + VALUE(*p++);
}
if (isdigit(*p)) {
c = (c<<3) + VALUE(*p++);
}
*r++ = c;
break;
case 'b':
*r++ = '\b';
break;
case 'f':
*r++ = '\f';
break;
case 'n':
*r++ = '\n';
break;
case 'r':
*r++ = '\r';
break;
case 't':
*r++ = '\t';
break;
case 'v':
*r++ = '\v';
break;
default:
*r++ = c;
}
} else {
*r++ = c;
}
}
return((char *) result);
}
char *
char *
c_charout(int32 c)
{
char str[2];
char str[2];
str[0] = (char) c;
str[1] = '\0';
str[0] = (char) c;
str[1] = '\0';
return (string_output(str, 1));
return (string_output(str, 1));
}
char *
char *
c_char2out(uint16 s)
{
return (string_output((char *) &s, 2));
return (string_output((char *) &s, 2));
}
char *
char *
c_char4out(uint32 s)
{
return (string_output((char *) &s, 4));
return (string_output((char *) &s, 4));
}
char *
char *
c_char8out(char *s)
{
return (string_output(s, 8));
return (string_output(s, 8));
}
char *
char *
c_char16out(char *s)
{
return (string_output(s, 16));
return (string_output(s, 16));
}
/*
* This can be used for text, bytea, SET and unknown data types
*/
char *
c_textout(struct varlena * vlena)
char *
c_textout(struct varlena *vlena)
{
int len = 0;
char *s = NULL;
int len = 0;
char *s = NULL;
if (vlena)
{
len = VARSIZE(vlena) - VARHDRSZ;
s = VARDATA(vlena);
}
return (string_output(s, len));
if (vlena) {
len = VARSIZE(vlena) - VARHDRSZ;
s = VARDATA(vlena);
}
return (string_output(s, len));
}
/*
* This can be used for varchar and bpchar strings
*/
char *
char *
c_varcharout(char *s)
{
int len;
int len = 0;
if (s)
{
len = *(int32 *) s - 4;
s += 4;
}
return (string_output(s, len));
if (s) {
len = *(int32*)s - 4;
s += 4;
}
return (string_output(s, len));
}
#ifdef 0
#if 0
struct varlena *
c_textin(char *str)
{
struct varlena *result;
int len;
struct varlena *result;
int len;
if (str == NULL)
{
return ((struct varlena *) NULL);
}
if (str == NULL) {
return ((struct varlena *) NULL);
}
result = (struct varlena *) string_input(str, 0, VARHDRSZ, &len);
VARSIZE(result) = len;
result = (struct varlena *) string_input(str, 0, VARHDRSZ, &len);
VARSIZE(result) = len;
return (result);
return (result);
}
char *
char *
c_char16in(char *str)
{
return (string_input(str, 16, 0, NULL));
return (string_input(str, 16, 0, NULL));
}
#endif
/* end of file */

View File

@ -0,0 +1,19 @@
#ifndef STRING_IO_H
#define STRING_IO_H
char *string_output(char *data, int size);
char *string_input(char *str, int size, int hdrsize, int *rtn_size);
char *c_charout(int32 c);
char *c_char2out(uint16 s);
char *c_char4out(uint32 s);
char *c_char8out(char *s);
char *c_char16out(char *s);
char *c_textout(struct varlena *vlena);
char *c_varcharout(char *s);
#if 0
struct varlena *c_textin(char *str);
char *c_char16in(char *str);
#endif
#endif

View File

@ -0,0 +1,104 @@
-- SQL code to define the new string I/O functions
-- This is not needed because escapes are handled by the parser
--
-- create function c_textin(opaque)
-- returns text
-- as 'MODULE_PATHNAME'
-- language 'c';
create function c_charout(opaque) returns int4
as 'MODULE_PATHNAME'
language 'c';
create function c_char2out(opaque) returns int4
as 'MODULE_PATHNAME'
language 'c';
create function c_char4out(opaque) returns int4
as 'MODULE_PATHNAME'
language 'c';
create function c_char8out(opaque) returns int4
as 'MODULE_PATHNAME'
language 'c';
create function c_char16out(opaque) returns int4
as 'MODULE_PATHNAME'
language 'c';
create function c_textout(opaque) returns int4
as 'MODULE_PATHNAME'
language 'c';
create function c_varcharout(opaque) returns int4
as 'MODULE_PATHNAME'
language 'c';
-- Define a function which sets the new output routines for char types
--
-- select c_mode();
--
create function c_mode() returns text
as 'update pg_type set typoutput=''c_charout'' where typname=''char'';
update pg_type set typoutput=''c_char2out'' where typname=''char2'';
update pg_type set typoutput=''c_char4out'' where typname=''char4'';
update pg_type set typoutput=''c_char8out'' where typname=''char8'';
update pg_type set typoutput=''c_char16out'' where typname=''char16'';
update pg_type set typoutput=''c_textout'' where typname=''text'';
update pg_type set typoutput=''c_textout'' where typname=''bytea'';
update pg_type set typoutput=''c_textout'' where typname=''unknown'';
update pg_type set typoutput=''c_textout'' where typname=''SET'';
update pg_type set typoutput=''c_varcharout'' where typname=''varchar'';
update pg_type set typoutput=''c_varcharout'' where typname=''bpchar'';
select ''c_mode''::text'
language 'sql';
-- Define a function which restores the original routines for char types
--
-- select pg_mode();
--
create function pg_mode() returns text
as 'update pg_type set typoutput=''charout'' where typname=''char'';
update pg_type set typoutput=''char2out'' where typname=''char2'';
update pg_type set typoutput=''char4out'' where typname=''char4'';
update pg_type set typoutput=''char8out'' where typname=''char8'';
update pg_type set typoutput=''char16out'' where typname=''char16'';
update pg_type set typoutput=''textout'' where typname=''text'';
update pg_type set typoutput=''textout'' where typname=''bytea'';
update pg_type set typoutput=''textout'' where typname=''unknown'';
update pg_type set typoutput=''textout'' where typname=''SET'';
update pg_type set typoutput=''varcharout'' where typname=''varchar'';
update pg_type set typoutput=''varcharout'' where typname=''bpchar'';
select ''pg_mode''::text'
language 'sql';
-- Use these if you want do the updates manually
--
-- update pg_type set typoutput='charout' where typname='char';
-- update pg_type set typoutput='char2out' where typname='char2';
-- update pg_type set typoutput='char4out' where typname='char4';
-- update pg_type set typoutput='char8out' where typname='char8';
-- update pg_type set typoutput='char16out' where typname='char16';
-- update pg_type set typoutput='textout' where typname='text';
-- update pg_type set typoutput='textout' where typname='bytea';
-- update pg_type set typoutput='textout' where typname='unknown';
-- update pg_type set typoutput='textout' where typname='SET';
-- update pg_type set typoutput='varcharout' where typname='varchar';
-- update pg_type set typoutput='varcharout' where typname='bpchar';
--
-- update pg_type set typoutput='c_charout' where typname='char';
-- update pg_type set typoutput='c_char2out' where typname='char2';
-- update pg_type set typoutput='c_char4out' where typname='char4';
-- update pg_type set typoutput='c_char8out' where typname='char8';
-- update pg_type set typoutput='c_char16out' where typname='char16';
-- update pg_type set typoutput='c_textout' where typname='text';
-- update pg_type set typoutput='c_textout' where typname='bytea';
-- update pg_type set typoutput='c_textout' where typname='unknown';
-- update pg_type set typoutput='c_textout' where typname='SET';
-- update pg_type set typoutput='c_varcharout' where typname='varchar';
-- update pg_type set typoutput='c_varcharout' where typname='bpchar';
-- end of file