summaryrefslogtreecommitdiff
path: root/postgresql_autodoc
diff options
context:
space:
mode:
Diffstat (limited to 'postgresql_autodoc')
-rw-r--r--postgresql_autodoc/Makefile103
-rw-r--r--postgresql_autodoc/config.log164
-rw-r--r--postgresql_autodoc/config.mk13
-rw-r--r--postgresql_autodoc/config.mk.in13
-rwxr-xr-xpostgresql_autodoc/config.status761
-rwxr-xr-xpostgresql_autodoc/configure2907
-rw-r--r--postgresql_autodoc/configure.ac56
-rw-r--r--postgresql_autodoc/dia.tmpl212
-rw-r--r--postgresql_autodoc/dot.tmpl19
-rw-r--r--postgresql_autodoc/html.tmpl308
-rwxr-xr-xpostgresql_autodoc/install-sh251
-rw-r--r--postgresql_autodoc/neato.tmpl22
-rwxr-xr-xpostgresql_autodoc/postgresql_autodoc1907
-rwxr-xr-xpostgresql_autodoc/postgresql_autodoc.pl1907
-rw-r--r--postgresql_autodoc/xml.tmpl204
-rw-r--r--postgresql_autodoc/zigzag.dia.tmpl224
16 files changed, 9071 insertions, 0 deletions
diff --git a/postgresql_autodoc/Makefile b/postgresql_autodoc/Makefile
new file mode 100644
index 0000000..fdddc1a
--- /dev/null
+++ b/postgresql_autodoc/Makefile
@@ -0,0 +1,103 @@
+# $Header: /cvsroot/autodoc/autodoc/Makefile,v 1.3 2006/05/16 18:57:24 rbt Exp $
+
+TEMPLATES = dia.tmpl dot.tmpl html.tmpl neato.tmpl xml.tmpl zigzag.dia.tmpl
+BINARY = postgresql_autodoc
+CONFIGFILE = config.mk
+
+RELEASE_FILES = Makefile config.mk.in configure \
+ configure.ac $(TEMPLATES) install-sh \
+ postgresql_autodoc.pl
+
+cur-dir := $(shell basename ${PWD})
+REAL_RELEASE_FILES = $(addprefix $(cur-dir)/,$(RELEASE_FILES))
+
+# Global dependencies
+ALWAYS_DEPEND = Makefile configure $(CONFIGFILE)
+
+
+####
+# Test to see if $(CONFIGFILE) has been generated. If so, include it. Otherwise we assume
+# it will be created for us.
+has_configmk := $(wildcard $(CONFIGFILE))
+
+ifeq ($(has_configmk),$(CONFIGFILE))
+include $(CONFIGFILE)
+endif
+
+####
+# ALL
+.PHONY: all
+all: $(ALWAYS_DEPEND) $(BINARY)
+
+####
+# Replace the /usr/bin/env perl with the supplied path
+# chmod to make testing easier
+$(BINARY): postgresql_autodoc.pl $(CONFIGFILE)
+ $(SED) -e "s,/usr/bin/env perl,$(PERL)," \
+ -e "s,@@TEMPLATE-DIR@@,$(datadir)," \
+ postgresql_autodoc.pl > $(BINARY)
+ -chmod +x $(BINARY)
+
+####
+# INSTALL Target
+.PHONY: install uninstall
+install: all $(ALWAYS_DEPEND)
+ $(INSTALL_SCRIPT) -d $(bindir)
+ $(INSTALL_SCRIPT) -d $(datadir)
+ $(INSTALL_SCRIPT) -m 755 $(BINARY) $(bindir)
+ for entry in $(TEMPLATES) ; \
+ do $(INSTALL_SCRIPT) -m 644 $${entry} $(datadir) ; \
+ done
+
+uninstall:
+ -$(RM) $(bindir)/$(BINARY)
+ for entry in $(TEMPLATES) ; \
+ do $(RM) $(datadir)/$${entry} ; \
+ done
+ -rmdir $(datadir)
+ -rmdir $(bindir)
+
+####
+# CLEAN / DISTRIBUTION-CLEAN / MAINTAINER-CLEAN Targets
+.PHONY: clean
+clean: $(ALWAYS_DEPEND)
+ $(RM) $(BINARY)
+
+.PHONY: distribution-clean distclean
+distribution-clean distclean: clean
+ $(RM) $(CONFIGFILE) config.log config.status
+ $(RM) -r autom4te.cache
+ $(RM) $(patsubst %.tmpl,*.%,$(wildcard *.tmpl))
+
+.PHONY: maintainer-clean
+maintainer-clean: distribution-clean
+ $(RM) configure
+
+####
+# Build a release
+#
+# Clean
+# Ensure configure is up to date
+# Commit any pending elements
+# Tar up the results
+.PHONY: release
+release: distribution-clean configure $(RELEASE_FILES)
+ @if [ -z ${VERSION} ] ; then \
+ echo "-------------------------------------------"; \
+ echo "VERSION needs to be specified for a release"; \
+ echo "-------------------------------------------"; \
+ false; \
+ fi
+ cvs2cl
+ -cvs commit
+ cd ../ && tar -czvf postgresql_autodoc-${VERSION}.tar.gz $(REAL_RELEASE_FILES)
+
+####
+# Build and Run configure files when configure or a template is updated.
+configure: configure.ac
+ autoconf
+
+# Fix my makefile, then execute myself
+$(CONFIGFILE) : config.mk.in configure
+ ./configure
+ $(MAKE) $(MAKEFLAGS)
diff --git a/postgresql_autodoc/config.log b/postgresql_autodoc/config.log
new file mode 100644
index 0000000..5ac7ad9
--- /dev/null
+++ b/postgresql_autodoc/config.log
@@ -0,0 +1,164 @@
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by configure, which was
+generated by GNU Autoconf 2.61. Invocation command line was
+
+ $ ./configure
+
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = tc4200
+uname -m = i686
+uname -r = 2.6.26
+uname -s = Linux
+uname -v = #30 PREEMPT Mon Jul 14 10:58:29 CEST 2008
+
+/usr/bin/uname -p = Intel(R) Pentium(R) M processor 1.73GHz
+/bin/uname -X = unknown
+
+/bin/arch = unknown
+/usr/bin/arch -k = unknown
+/usr/convex/getsysinfo = unknown
+/usr/bin/hostinfo = unknown
+/bin/machine = unknown
+/usr/bin/oslevel = unknown
+/bin/universe = unknown
+
+PATH: /usr/local/bin
+PATH: /usr/bin
+PATH: /bin
+PATH: /opt/bin
+PATH: /usr/i686-pc-linux-gnu/arm-gentoo-linux-uclibc/gcc-bin/4.1.2
+PATH: /usr/i686-pc-linux-gnu/arm-linux-uclibc/gcc-bin/4.1.2
+PATH: /usr/i686-pc-linux-gnu/gcc-bin/4.3.1
+PATH: /usr/i686-pc-linux-gnu/powerpc-fendt-linux-gnu/gcc-bin/4.2.2
+PATH: /opt/e17/bin
+PATH: /usr/kde/3.5/bin
+PATH: /usr/qt/3/bin
+PATH: /usr/games/bin
+PATH: /opt/bin
+PATH: /opt/ACE_wrappers/bin
+PATH: /opt/ACE_wrappers/TAO/orbsvcs/Naming_Service
+PATH: /home/linutronix/scripts
+PATH: /home/linutronix/scripts
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+configure:1665: checking for a BSD-compatible install
+configure:1721: result: /usr/bin/install -c
+configure:1737: checking for sed
+configure:1756: found /bin/sed
+configure:1768: result: /bin/sed
+configure:1824: checking for perl
+configure:1843: found /usr/bin/perl
+configure:1855: result: /usr/bin/perl
+configure:1884: checking DBI
+configure:1893: result: yes
+configure:1884: checking DBD::Pg
+configure:1893: result: yes
+configure:1884: checking Fcntl
+configure:1893: result: yes
+configure:1884: checking HTML::Template
+configure:1893: result: yes
+configure:1884: checking Term::ReadKey
+configure:1893: result: yes
+configure:2031: creating ./config.status
+
+## ---------------------- ##
+## Running config.status. ##
+## ---------------------- ##
+
+This file was extended by config.status, which was
+generated by GNU Autoconf 2.61. Invocation command line was
+
+ CONFIG_FILES =
+ CONFIG_HEADERS =
+ CONFIG_LINKS =
+ CONFIG_COMMANDS =
+ $ ./config.status
+
+on tc4200
+
+config.status:570: creating config.mk
+config.status:705: WARNING: config.mk.in seems to ignore the --datarootdir setting
+
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+
+ac_cv_env_build_alias_set=
+ac_cv_env_build_alias_value=
+ac_cv_env_host_alias_set=
+ac_cv_env_host_alias_value=
+ac_cv_env_target_alias_set=
+ac_cv_env_target_alias_value=
+ac_cv_path_PERL=/usr/bin/perl
+ac_cv_path_SED=/bin/sed
+ac_cv_path_install='/usr/bin/install -c'
+
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+
+DEFS='-DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\"'
+ECHO_C=''
+ECHO_N='-n'
+ECHO_T=''
+INSTALL_DATA='${INSTALL} -m 644'
+INSTALL_PROGRAM='${INSTALL}'
+INSTALL_SCRIPT='${INSTALL}'
+LIBOBJS=''
+LIBS=''
+LTLIBOBJS=''
+PACKAGE_BUGREPORT=''
+PACKAGE_NAME=''
+PACKAGE_STRING=''
+PACKAGE_TARNAME=''
+PACKAGE_VERSION=''
+PATH_SEPARATOR=':'
+PERL='/usr/bin/perl'
+SED='/bin/sed'
+SHELL='/bin/sh'
+bindir='${exec_prefix}/bin'
+build_alias=''
+datadir='${datarootdir}'
+datarootdir='${prefix}/share'
+docdir='${datarootdir}/doc/${PACKAGE}'
+dvidir='${docdir}'
+exec_prefix='${prefix}'
+host_alias=''
+htmldir='${docdir}'
+includedir='${prefix}/include'
+infodir='${datarootdir}/info'
+libdir='${exec_prefix}/lib'
+libexecdir='${exec_prefix}/libexec'
+localedir='${datarootdir}/locale'
+localstatedir='${prefix}/var'
+mandir='${datarootdir}/man'
+oldincludedir='/usr/include'
+pdfdir='${docdir}'
+prefix='/usr/local'
+program_transform_name='s,x,x,'
+psdir='${docdir}'
+sbindir='${exec_prefix}/sbin'
+sharedstatedir='${prefix}/com'
+sysconfdir='${prefix}/etc'
+target_alias=''
+
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+
+#define PACKAGE_NAME ""
+#define PACKAGE_TARNAME ""
+#define PACKAGE_VERSION ""
+#define PACKAGE_STRING ""
+#define PACKAGE_BUGREPORT ""
+
+configure: exit 0
diff --git a/postgresql_autodoc/config.mk b/postgresql_autodoc/config.mk
new file mode 100644
index 0000000..73bd570
--- /dev/null
+++ b/postgresql_autodoc/config.mk
@@ -0,0 +1,13 @@
+SHELL = /bin/sh
+
+
+# Configure replacements
+INSTALL_SCRIPT = /usr/bin/install -c
+PERL = /usr/bin/perl
+SED = /bin/sed
+
+# installation directories
+prefix = /usr/local
+exec_prefix= ${prefix}
+bindir = ${exec_prefix}/bin
+datadir = ${prefix}/share/postgresql_autodoc
diff --git a/postgresql_autodoc/config.mk.in b/postgresql_autodoc/config.mk.in
new file mode 100644
index 0000000..ddcee1a
--- /dev/null
+++ b/postgresql_autodoc/config.mk.in
@@ -0,0 +1,13 @@
+SHELL = /bin/sh
+VPATH = @srcdir@
+
+# Configure replacements
+INSTALL_SCRIPT = @INSTALL@
+PERL = @PERL@
+SED = @SED@
+
+# installation directories
+prefix = @prefix@
+exec_prefix= @exec_prefix@
+bindir = @bindir@
+datadir = @datadir@/postgresql_autodoc
diff --git a/postgresql_autodoc/config.status b/postgresql_autodoc/config.status
new file mode 100755
index 0000000..5f5e3a1
--- /dev/null
+++ b/postgresql_autodoc/config.status
@@ -0,0 +1,761 @@
+#! /bin/sh
+# Generated by configure.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=${CONFIG_SHELL-/bin/sh}
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.61. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+# Files that config.status was made for.
+config_files=" config.mk"
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+ac_cs_version="\
+config.status
+configured by ./configure, generated by GNU Autoconf 2.61,
+ with options \"\"
+
+Copyright (C) 2006 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='/home/manut/postgresql_autodoc'
+srcdir='.'
+INSTALL='/usr/bin/install -c'
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+ echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+if $ac_cs_recheck; then
+ echo "running CONFIG_SHELL=/bin/sh /bin/sh ./configure " $ac_configure_extra_args " --no-create --no-recursion" >&6
+ CONFIG_SHELL=/bin/sh
+ export CONFIG_SHELL
+ exec /bin/sh "./configure" $ac_configure_extra_args --no-create --no-recursion
+fi
+
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ echo "$ac_log"
+} >&5
+
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;;
+
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+#
+# Set up the sed scripts for CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "$CONFIG_FILES"; then
+
+cat >"$tmp/subs-1.sed" <<\CEOF
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+s,@SHELL@,|#_!!_#|/bin/sh,g
+s,@PATH_SEPARATOR@,|#_!!_#|:,g
+s,@PACKAGE_NAME@,|#_!!_#|,g
+s,@PACKAGE_TARNAME@,|#_!!_#|,g
+s,@PACKAGE_VERSION@,|#_!!_#|,g
+s,@PACKAGE_STRING@,|#_!!_#|,g
+s,@PACKAGE_BUGREPORT@,|#_!!_#|,g
+s,@exec_prefix@,|#_!!_#|${prefix},g
+s,@prefix@,|#_!!_#|/usr/local,g
+s,@program_transform_name@,|#_!!_#|s\,x\,x\,,g
+s,@bindir@,|#_!!_#|${exec_prefix}/bin,g
+s,@sbindir@,|#_!!_#|${exec_prefix}/sbin,g
+s,@libexecdir@,|#_!!_#|${exec_prefix}/libexec,g
+s,@datarootdir@,|#_!!_#|${prefix}/share,g
+s,@datadir@,|#_!!_#|${datarootdir},g
+s,@sysconfdir@,|#_!!_#|${prefix}/etc,g
+s,@sharedstatedir@,|#_!!_#|${prefix}/com,g
+s,@localstatedir@,|#_!!_#|${prefix}/var,g
+s,@includedir@,|#_!!_#|${prefix}/include,g
+s,@oldincludedir@,|#_!!_#|/usr/include,g
+s,@docdir@,|#_!!_#|${datarootdir}/doc/${PACKAGE},g
+s,@infodir@,|#_!!_#|${datarootdir}/info,g
+s,@htmldir@,|#_!!_#|${docdir},g
+s,@dvidir@,|#_!!_#|${docdir},g
+s,@pdfdir@,|#_!!_#|${docdir},g
+s,@psdir@,|#_!!_#|${docdir},g
+s,@libdir@,|#_!!_#|${exec_prefix}/lib,g
+s,@localedir@,|#_!!_#|${datarootdir}/locale,g
+s,@mandir@,|#_!!_#|${datarootdir}/man,g
+s,@DEFS@,|#_!!_#|-DPACKAGE_NAME=\\"\\" -DPACKAGE_TARNAME=\\"\\" -DPACKAGE_VERSION=\\"\\" -DPACKAGE_STRING=\\"\\" -DPACKAGE_BUGREPORT=\\"\\",g
+s,@ECHO_C@,|#_!!_#|,g
+s,@ECHO_N@,|#_!!_#|-n,g
+s,@ECHO_T@,|#_!!_#|,g
+s,@LIBS@,|#_!!_#|,g
+s,@build_alias@,|#_!!_#|,g
+s,@host_alias@,|#_!!_#|,g
+s,@target_alias@,|#_!!_#|,g
+s,@INSTALL_PROGRAM@,|#_!!_#|${INSTALL},g
+s,@INSTALL_SCRIPT@,|#_!!_#|${INSTALL},g
+s,@INSTALL_DATA@,|#_!!_#|${INSTALL} -m 644,g
+s,@SED@,|#_!!_#|/bin/sed,g
+s,@PERL@,|#_!!_#|/usr/bin/perl,g
+s,@LIBOBJS@,|#_!!_#|,g
+s,@LTLIBOBJS@,|#_!!_#|,g
+:end
+s/|#_!!_#|//g
+CEOF
+fi # test -n "$CONFIG_FILES"
+
+
+for ac_tag in :F $CONFIG_FILES
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
+echo "$as_me: error: Invalid tag $ac_tag." >&2;}
+ { (exit 1); exit 1; }; };;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+ ac_file_inputs="$ac_file_inputs $ac_f"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input="Generated from "`IFS=:
+ echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ fi
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin";;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir="$ac_dir"
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+case `sed -n '/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+' $ac_file_inputs` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+ ac_datarootdir_hack='
+ s&@datadir@&${datarootdir}&g
+ s&@docdir@&${datarootdir}/doc/${PACKAGE}&g
+ s&@infodir@&${datarootdir}/info&g
+ s&@localedir@&${datarootdir}/locale&g
+ s&@mandir@&${datarootdir}/man&g
+ s&\${datarootdir}&${prefix}/share&g' ;;
+esac
+ sed "/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}
+
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s&@configure_input@&$configure_input&;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out"; rm -f "$tmp/out";;
+ *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
+ esac
+ ;;
+
+
+
+ esac
+
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
diff --git a/postgresql_autodoc/configure b/postgresql_autodoc/configure
new file mode 100755
index 0000000..776cb9d
--- /dev/null
+++ b/postgresql_autodoc/configure
@@ -0,0 +1,2907 @@
+#! /bin/sh
+# From configure.ac Header: /cvsroot/autodoc/autodoc/configure.ac.
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.61.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+ if (eval ":") 2>/dev/null; then
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+
+ if test $as_have_required = yes && (eval ":
+(as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=\$LINENO
+ as_lineno_2=\$LINENO
+ test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+ test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+ :
+else
+ as_candidate_shells=
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ case $as_dir in
+ /*)
+ for as_base in sh bash ksh sh5; do
+ as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+ done;;
+ esac
+done
+IFS=$as_save_IFS
+
+
+ for as_shell in $as_candidate_shells $SHELL; do
+ # Try only shells that exist, to save several forks.
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { ("$as_shell") 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+_ASEOF
+}; then
+ CONFIG_SHELL=$as_shell
+ as_have_required=yes
+ if { "$as_shell" 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+(as_func_return () {
+ (exit $1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+ break
+fi
+
+fi
+
+ done
+
+ if test "x$CONFIG_SHELL" != x; then
+ for as_var in BASH_ENV ENV
+ do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ done
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+ if test $as_have_required = no; then
+ echo This script requires a shell more modern than all the
+ echo shells that I found on your system. Please install a
+ echo modern shell, or manually run the script under such a
+ echo shell if you do have one.
+ { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+ echo No shell found that supports shell functions.
+ echo Please tell autoconf@gnu.org about your system,
+ echo including any error possibly output before this
+ echo message
+}
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="postgresql_autodoc.pl"
+ac_subst_vars='SHELL
+PATH_SEPARATOR
+PACKAGE_NAME
+PACKAGE_TARNAME
+PACKAGE_VERSION
+PACKAGE_STRING
+PACKAGE_BUGREPORT
+exec_prefix
+prefix
+program_transform_name
+bindir
+sbindir
+libexecdir
+datarootdir
+datadir
+sysconfdir
+sharedstatedir
+localstatedir
+includedir
+oldincludedir
+docdir
+infodir
+htmldir
+dvidir
+pdfdir
+psdir
+libdir
+localedir
+mandir
+DEFS
+ECHO_C
+ECHO_N
+ECHO_T
+LIBS
+build_alias
+host_alias
+target_alias
+INSTALL_PROGRAM
+INSTALL_SCRIPT
+INSTALL_DATA
+SED
+PERL
+LIBOBJS
+LTLIBOBJS'
+ac_subst_files=''
+ ac_precious_vars='build_alias
+host_alias
+target_alias'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+ eval enable_$ac_feature=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+ eval enable_$ac_feature=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+ eval with_$ac_package=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+ eval with_$ac_package=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute directory names.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ { echo "$as_me: error: Working directory cannot be determined" >&2
+ { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ { echo "$as_me: error: pwd does not report name of working directory" >&2
+ { (exit 1); exit 1; }; }
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$0" ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
+ { (exit 1); exit 1; }; }
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-perl-prefix Location of Perl
+
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" || continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.61
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.61. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args '$ac_arg'"
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -n "$CONFIG_SITE"; then
+ set x "$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+ set x "$prefix/share/config.site" "$prefix/etc/config.site"
+else
+ set x "$ac_default_prefix/share/config.site" \
+ "$ac_default_prefix/etc/config.site"
+fi
+shift
+for ac_site_file
+do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+# Programs
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+IFS=$as_save_IFS
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+for ac_prog in sed
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_SED+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $SED in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_SED="$SED" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_dummy="$PATH:/bin:/usr/bin"
+for as_dir in $as_dummy
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+SED=$ac_cv_path_SED
+if test -n "$SED"; then
+ { echo "$as_me:$LINENO: result: $SED" >&5
+echo "${ECHO_T}$SED" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ test -n "$SED" && break
+done
+
+
+# Check for Perl
+
+# Check whether --with-perl-prefix was given.
+if test "${with_perl_prefix+set}" = set; then
+ withval=$with_perl_prefix; PERLPATH=$withval
+else
+ PERLPATH=""
+fi
+
+
+if ( test -n "$PERLPATH" -a "`echo $PERLPATH | cut -c-3`" = "../" ); then
+ PERLPATH="$PWD/$PERLPATH"
+fi
+
+PERL=""
+if ( test -n "$PERLPATH" ); then
+ as_ac_File=`echo "ac_cv_file_"$PERLPATH/bin/perl"" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for \"$PERLPATH/bin/perl\"" >&5
+echo $ECHO_N "checking for \"$PERLPATH/bin/perl\"... $ECHO_C" >&6; }
+if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ test "$cross_compiling" = yes &&
+ { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
+echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
+ { (exit 1); exit 1; }; }
+if test -r ""$PERLPATH/bin/perl""; then
+ eval "$as_ac_File=yes"
+else
+ eval "$as_ac_File=no"
+fi
+fi
+ac_res=`eval echo '${'$as_ac_File'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_File'}'` = yes; then
+ PERL="$PERLPATH/bin/perl"
+fi
+
+else
+ for ac_prog in perl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_PERL+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $PERL in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_dummy="$PATH:/usr/bin:/usr/local/bin:/usr/pkg/bin:/usr/local/perl/bin:/opt/sfw/bin"
+for as_dir in $as_dummy
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+PERL=$ac_cv_path_PERL
+if test -n "$PERL"; then
+ { echo "$as_me:$LINENO: result: $PERL" >&5
+echo "${ECHO_T}$PERL" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+ test -n "$PERL" && break
+done
+
+fi
+if ( test -z "$PERL" ); then
+ { { echo "$as_me:$LINENO: error: \"Perl is required\"" >&5
+echo "$as_me: error: \"Perl is required\"" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+
+# Check that Perl Libraries are available:
+# DBI
+# DBD::Pg
+# Fcntl
+# HTML::Template
+# Term::ReadKey
+#
+# Output of if test redirected to /dev/null to keep quiet
+for module in DBI DBD::Pg Fcntl HTML::Template Term::ReadKey ; do
+ { echo "$as_me:$LINENO: checking ${module}" >&5
+echo $ECHO_N "checking ${module}... $ECHO_C" >&6; }
+ if ! (${PERL} -e "use ${module}" 2>&1 /dev/null ) ; then
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ { { echo "$as_me:$LINENO: error: Perl module ${module} is required" >&5
+echo "$as_me: error: Perl module ${module} is required" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ fi
+done
+
+
+ac_config_files="$ac_config_files config.mk"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { echo "$as_me:$LINENO: updating cache $cache_file" >&5
+echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+t clear
+:clear
+s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+ g
+ s/^\n//
+ s/\n/ /g
+ p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.61. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+# Files that config.status was made for.
+config_files="$ac_config_files"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.61,
+ with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2006 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+ echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ CONFIG_SHELL=$SHELL
+ export CONFIG_SHELL
+ exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;;
+
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+#
+# Set up the sed scripts for CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "$CONFIG_FILES"; then
+
+_ACEOF
+
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ cat >conf$$subs.sed <<_ACEOF
+SHELL!$SHELL$ac_delim
+PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
+PACKAGE_NAME!$PACKAGE_NAME$ac_delim
+PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
+PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
+PACKAGE_STRING!$PACKAGE_STRING$ac_delim
+PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
+exec_prefix!$exec_prefix$ac_delim
+prefix!$prefix$ac_delim
+program_transform_name!$program_transform_name$ac_delim
+bindir!$bindir$ac_delim
+sbindir!$sbindir$ac_delim
+libexecdir!$libexecdir$ac_delim
+datarootdir!$datarootdir$ac_delim
+datadir!$datadir$ac_delim
+sysconfdir!$sysconfdir$ac_delim
+sharedstatedir!$sharedstatedir$ac_delim
+localstatedir!$localstatedir$ac_delim
+includedir!$includedir$ac_delim
+oldincludedir!$oldincludedir$ac_delim
+docdir!$docdir$ac_delim
+infodir!$infodir$ac_delim
+htmldir!$htmldir$ac_delim
+dvidir!$dvidir$ac_delim
+pdfdir!$pdfdir$ac_delim
+psdir!$psdir$ac_delim
+libdir!$libdir$ac_delim
+localedir!$localedir$ac_delim
+mandir!$mandir$ac_delim
+DEFS!$DEFS$ac_delim
+ECHO_C!$ECHO_C$ac_delim
+ECHO_N!$ECHO_N$ac_delim
+ECHO_T!$ECHO_T$ac_delim
+LIBS!$LIBS$ac_delim
+build_alias!$build_alias$ac_delim
+host_alias!$host_alias$ac_delim
+target_alias!$target_alias$ac_delim
+INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
+INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim
+INSTALL_DATA!$INSTALL_DATA$ac_delim
+SED!$SED$ac_delim
+PERL!$PERL$ac_delim
+LIBOBJS!$LIBOBJS$ac_delim
+LTLIBOBJS!$LTLIBOBJS$ac_delim
+_ACEOF
+
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 44; then
+ break
+ elif $ac_last_try; then
+ { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+ ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+ ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+:end
+s/|#_!!_#|//g
+CEOF$ac_eof
+_ACEOF
+
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+fi # test -n "$CONFIG_FILES"
+
+
+for ac_tag in :F $CONFIG_FILES
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
+echo "$as_me: error: Invalid tag $ac_tag." >&2;}
+ { (exit 1); exit 1; }; };;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+ ac_file_inputs="$ac_file_inputs $ac_f"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input="Generated from "`IFS=:
+ echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ fi
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin";;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir="$ac_dir"
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+case `sed -n '/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+' $ac_file_inputs` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s&@configure_input@&$configure_input&;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out"; rm -f "$tmp/out";;
+ *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
+ esac
+ ;;
+
+
+
+ esac
+
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/postgresql_autodoc/configure.ac b/postgresql_autodoc/configure.ac
new file mode 100644
index 0000000..128a044
--- /dev/null
+++ b/postgresql_autodoc/configure.ac
@@ -0,0 +1,56 @@
+AC_PREREQ(2.53)
+AC_REVISION($Header: /cvsroot/autodoc/autodoc/configure.ac,v 1.2 2007/01/02 13:53:19 rbt Exp $)
+AC_INIT(postgresql_autodoc.pl)
+
+
+# Programs
+AC_PROG_INSTALL
+
+AC_PATH_PROGS([SED], [sed], ,
+ [$PATH:/bin:/usr/bin])
+
+# Check for Perl
+AC_ARG_WITH(perl-prefix,
+ [ --with-perl-prefix Location of Perl],
+ PERLPATH=$withval,
+ PERLPATH="")
+
+if ( test -n "$PERLPATH" -a "`echo $PERLPATH | cut -c-3`" = "../" ); then
+ PERLPATH="$PWD/$PERLPATH"
+fi
+
+PERL=""
+if ( test -n "$PERLPATH" ); then
+ AC_CHECK_FILE("$PERLPATH/bin/perl",PERL="$PERLPATH/bin/perl")
+else
+ AC_PATH_PROGS([PERL], [perl], ,
+ [$PATH:/usr/bin:/usr/local/bin:/usr/pkg/bin:/usr/local/perl/bin:/opt/sfw/bin])
+fi
+if ( test -z "$PERL" ); then
+ AC_MSG_ERROR("Perl is required")
+fi
+AC_SUBST(PERL)
+
+
+# Check that Perl Libraries are available:
+# DBI
+# DBD::Pg
+# Fcntl
+# HTML::Template
+# Term::ReadKey
+#
+# Output of if test redirected to /dev/null to keep quiet
+for module in DBI DBD::Pg Fcntl HTML::Template Term::ReadKey ; do
+ AC_MSG_CHECKING(${module})
+ if [ ! (${PERL} -e "use ${module}" 2>&1 /dev/null ) ]; then
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR(Perl module ${module} is required)
+ else
+ AC_MSG_RESULT(yes)
+ fi
+done
+
+
+AC_OUTPUT([
+config.mk
+])
diff --git a/postgresql_autodoc/dia.tmpl b/postgresql_autodoc/dia.tmpl
new file mode 100644
index 0000000..88143e9
--- /dev/null
+++ b/postgresql_autodoc/dia.tmpl
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
+ <dia:layer name="Background" visible="true">
+<!-- TMPL_LOOP name="schemas" -->
+<!-- TMPL_IF name="number_of_schemas" -->
+ <dia:group>
+<!-- /TMPL_IF name="number_of_schemas" -->
+<!-- TMPL_LOOP name="tables" -->
+ <dia:object type="UML - Class" version="0" id="O<!-- TMPL_VAR ESCAPE="HTML" name="object_id" -->">
+ <dia:attribute name="obj_pos">
+ <dia:point val="0,0"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-0.05,-0.05;16.4,6.65"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="0,0"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="16.350000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="6.6000000000000005"/>
+ </dia:attribute>
+ <dia:attribute name="name">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="table" -->#</dia:string>
+ </dia:attribute>
+<!-- TMPL_IF name="number_of_schemas" -->
+ <dia:attribute name="stereotype">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="schema" -->#</dia:string>
+ </dia:attribute>
+<!-- /TMPL_IF name="number_of_schemas" -->
+ <dia:attribute name="comment">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="table_comment_dia" -->#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="abstract">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="suppress_attributes">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="suppress_operations">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="visible_attributes">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="visible_comments">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="wrap_operations">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="wrap_after_char">
+ <dia:int val="40"/>
+ </dia:attribute>
+ <dia:attribute name="line_color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="fill_color">
+ <dia:color val="#ffffff"/>
+ </dia:attribute>
+ <dia:attribute name="text_color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="normal_font">
+ <dia:font family="monospace" style="0" name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="abstract_font">
+ <dia:font family="monospace" style="88" name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="polymorphic_font">
+ <dia:font family="monospace" style="8" name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="classname_font">
+ <dia:font family="sans" style="80" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="abstract_classname_font">
+ <dia:font family="sans" style="88" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="comment_font">
+ <dia:font family="sans" style="8" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="font_height">
+ <dia:real val="0.80000000000000004"/>
+ </dia:attribute>
+ <dia:attribute name="polymorphic_font_height">
+ <dia:real val="0.80000000000000004"/>
+ </dia:attribute>
+ <dia:attribute name="abstract_font_height">
+ <dia:real val="0.80000000000000004"/>
+ </dia:attribute>
+ <dia:attribute name="classname_font_height">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="abstract_classname_font_height">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="comment_font_height">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="attributes">
+<!-- TMPL_LOOP name="columns" -->
+ <dia:composite type="umlattribute">
+ <dia:attribute name="name">
+ <dia:string>#<!-- TMPL_IF name="column_primary_key" -->PK<!-- TMPL_ELSE name="column_primary_key" --> <!-- /TMPL_IF name="column_primary_key" --><!-- TMPL_VAR ESCAPE="HTML" name="column" -->#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="type">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="column_type" -->#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="value">
+<!-- TMPL_IF name="column_default_short" -->
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="column_default_short" -->#</dia:string>
+<!-- TMPL_ELSE name="column_default_short" -->
+ <dia:string/>
+<!-- /TMPL_IF name="column_default_short" -->
+ </dia:attribute>
+ <dia:attribute name="visibility">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ <dia:attribute name="abstract">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="class_scope">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ </dia:composite>
+<!-- /TMPL_LOOP name="columns" -->
+ </dia:attribute>
+<!-- TMPL_IF name="constraints" -->
+ <dia:attribute name="visible_operations">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="operations">
+<!-- TMPL_LOOP name="constraints" -->
+ <dia:composite type="umloperation">
+ <dia:attribute name="name">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="constraint_name" -->#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="visibility">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ <dia:attribute name="abstract">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="class_scope">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="parameters">
+ <dia:composite type="umlparameter">
+ <dia:attribute name="name">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="constraint_short" -->#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="type">
+ <dia:string>##</dia:string>
+ </dia:attribute>
+ <dia:attribute name="value">
+ <dia:string/>
+ </dia:attribute>
+ <dia:attribute name="kind">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:composite>
+<!-- /TMPL_LOOP name="constraints" -->
+ </dia:attribute>
+<!-- TMPL_ELSE name="constraints" -->
+ <dia:attribute name="visible_operations">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="operations"/>
+<!-- /TMPL_IF name="constraints" -->
+ <dia:attribute name="template">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="templates"/>
+ </dia:object>
+<!-- /TMPL_LOOP name="tables" -->
+<!-- TMPL_IF name="number_of_schemas" -->
+ </dia:group>
+<!-- /TMPL_IF name="number_of_schemas" -->
+<!-- /TMPL_LOOP name="schemas" -->
+<!-- TMPL_LOOP name="fk_links" -->
+ <dia:object type="UML - Constraint" version="0" id="O<!-- TMPL_VAR ESCAPE="HTML" name="object_id" -->">
+ <dia:attribute name="obj_pos">
+ <dia:point val="0,3.5"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-0.0515705,2.29861;25.1127,3.55157"/>
+ </dia:attribute>
+ <dia:attribute name="conn_endpoints">
+ <dia:point val="0,3.5"/>
+ <dia:point val="25.05,2.7"/>
+ </dia:attribute>
+ <dia:attribute name="constraint">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="fk_link_name" -->#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="text_pos">
+ <dia:point val="12.525,3.1"/>
+ </dia:attribute>
+ <dia:attribute name="line_colour">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O<!-- TMPL_VAR ESCAPE="HTML" name="handle0_to" -->" connection="<!-- TMPL_VAR ESCAPE="HTML" name="handle0_connection_dia" -->"/>
+ <dia:connection handle="1" to="O<!-- TMPL_VAR ESCAPE="HTML" name="handle1_to" -->" connection="<!-- TMPL_VAR ESCAPE="HTML" name="handle1_connection_dia" -->"/>
+ </dia:connections>
+ </dia:object>
+<!-- /TMPL_LOOP name="fk_links" -->
+ </dia:layer>
+</dia:diagram>
diff --git a/postgresql_autodoc/dot.tmpl b/postgresql_autodoc/dot.tmpl
new file mode 100644
index 0000000..1cb9ca6
--- /dev/null
+++ b/postgresql_autodoc/dot.tmpl
@@ -0,0 +1,19 @@
+digraph g {
+graph [
+rankdir = "LR",
+concentrate = true,
+ratio = auto
+];
+node [
+fontsize = "10",
+shape = record
+];
+edge [
+];
+<TMPL_LOOP name="schemas"><TMPL_LOOP name="tables"><TMPL_UNLESS name="view_definition">
+"<TMPL_IF name="number_of_schemas"><TMPL_VAR name="schema_dot">.</TMPL_IF name="number_of_schemas"><TMPL_VAR name="table_dot">" [shape = plaintext, label = < <TABLE BORDER="1" CELLBORDER="0" CELLSPACING="0"> <TR ><TD PORT="ltcol0"> </TD> <TD bgcolor="grey90" border="1" COLSPAN="4"> \N </TD> <TD PORT="rtcol0"></TD></TR> <TMPL_LOOP name="columns"> <TR><TD PORT="ltcol<TMPL_VAR name="column_number">" ></TD><TD align="left" > <TMPL_VAR name="column_dot"> </TD><TD align="left" > <TMPL_VAR name="column_type"> </TD><TD align="left" > <TMPL_LOOP name="column_constraints"><TMPL_IF NAME="column_primary_key">PK</TMPL_IF NAME="column_primary_key"></TMPL_LOOP name="column_constraints"> </TD><TD align="left" > <TMPL_LOOP name="column_constraints"><TMPL_IF NAME="column_fk"><TMPL_IF NAME="__first__">FK</TMPL_IF NAME="__first__"></TMPL_IF NAME="column_fk"></TMPL_LOOP name="column_constraints"> </TD><TD align="left" PORT="rtcol<TMPL_VAR name="column_number">"> </TD></TR></TMPL_LOOP name="columns"> </TABLE>> ];
+</TMPL_UNLESS name="view_definition"></TMPL_LOOP name="tables"></TMPL_LOOP name="schemas">
+
+<TMPL_LOOP name="fk_links">
+"<TMPL_IF name="number_of_schemas"><TMPL_VAR name="handle0_schema">.</TMPL_IF name="number_of_schemas"><TMPL_VAR name="handle0_name">":rtcol<TMPL_VAR name="handle0_connection"> -> "<TMPL_IF name="number_of_schemas"><TMPL_VAR name="handle1_schema">.</TMPL_IF name="number_of_schemas"><TMPL_VAR name="handle1_name">":ltcol<TMPL_VAR name="handle1_connection"> [label="<TMPL_VAR name="fk_link_name_dot">"];</TMPL_LOOP name="fk_links">
+}
diff --git a/postgresql_autodoc/html.tmpl b/postgresql_autodoc/html.tmpl
new file mode 100644
index 0000000..4830b15
--- /dev/null
+++ b/postgresql_autodoc/html.tmpl
@@ -0,0 +1,308 @@
+<!-- $Header: /cvsroot/autodoc/autodoc/html.tmpl,v 1.4 2006/05/16 19:01:27 rbt Exp $ -->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+
+<html>
+ <head>
+ <title>Index for <!-- TMPL_VAR ESCAPE="HTML" name="database" --></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <style type="text/css">
+ BODY {
+ color: #000000;
+ background-color: #FFFFFF;
+ font-family: Helvetica, sans-serif;
+ }
+
+ P {
+ margin-top: 5px;
+ margin-bottom: 5px;
+ }
+
+ P.w3ref {
+ font-size: 8pt;
+ font-style: italic;
+ text-align: right;
+ }
+
+ P.detail {
+ font-size: 10pt;
+ }
+
+ .error {
+ color: #FFFFFF;
+ background-color: #FF0000;
+ }
+
+ H1, H2, H3, H4, H5, H6 {
+ }
+
+ OL {
+ list-style-type: upper-alpha;
+ }
+
+ UL.topic {
+ list-style-type: upper-alpha;
+ }
+
+ LI.topic {
+ font-weight : bold;
+ }
+
+ HR {
+ color: #00FF00;
+ background-color: #808080;
+ }
+
+ TABLE {
+ border-width: medium;
+ padding: 3px;
+ background-color: #000000;
+ width: 90%;
+ }
+
+ CAPTION {
+ text-transform: capitalize;
+ font-weight : bold;
+ font-size: 14pt;
+ }
+
+ TH {
+ color: #FFFFFF;
+ background-color: #000000;
+ text-align: left;
+ }
+
+ TR {
+ color: #000000;
+ background-color: #000000;
+ vertical-align: top;
+ }
+
+ TR.tr0 {
+ background-color: #F0F0F0;
+ }
+
+ TR.tr1 {
+ background-color: #D8D8D8;
+ }
+
+ TD {
+ font-size: 12pt;
+ }
+
+ TD.col0 {
+ font-weight : bold;
+ width: 20%;
+ }
+
+ TD.col1 {
+ font-style: italic;
+ width: 15%;
+ }
+
+ TD.col2 {
+ font-size: 12px;
+ }
+ </style>
+ <link rel="stylesheet" type="text/css" media="all" href="all.css">
+ <link rel="stylesheet" type="text/css" media="screen" href="screen.css">
+ <link rel="stylesheet" type="text/css" media="print" href="print.css">
+ <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+ </head>
+ <body>
+
+ <!-- Primary Index -->
+ <p><!-- TMPL_VAR ESCAPE="HTML" name="database_comment" --><br><br>Dumped on <!-- TMPL_VAR ESCAPE="HTML" name="dumped_on" --></p>
+<h1><a name="index">Index of database - <!-- TMPL_VAR ESCAPE="HTML" name="database" --></a></h1>
+<ul>
+ <!-- TMPL_LOOP name="schemas" -->
+ <li><a name="<!-- TMPL_VAR ESCAPE="HTML" name="schema_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="schema" --></a></li><ul>
+ <!-- TMPL_LOOP name="tables" --><li><a href="#<!-- TMPL_VAR ESCAPE="URL" name="table_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="table" --></a></li><!-- /TMPL_LOOP name="tables" -->
+ <!-- TMPL_LOOP name="functions" --><li><a href="#<!-- TMPL_VAR ESCAPE="URL" name="function_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="function" --></a></li><!-- /TMPL_LOOP name="functions" -->
+ </ul>
+ <!-- /TMPL_LOOP name="schemas" -->
+</ul>
+
+ <!-- Schema Creation -->
+ <!-- TMPL_LOOP name="schemas" --><!-- <!-- TMPL_VAR ESCAPE="HTML" name="schema" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" --> -->
+
+ <!-- TMPL_IF name="number_of_schemas" -->
+ <hr>
+ <h1>Schema <!-- TMPL_VAR ESCAPE="HTML" name="schema" --></h1>
+ <!-- TMPL_IF name="schema_comment" -->
+ <p><!-- TMPL_VAR name="schema_comment" --></p>
+ <!-- /TMPL_IF name="schema_comment" -->
+
+ <!-- /TMPL_IF name="number_of_schemas" -->
+ <!-- TMPL_LOOP name="tables" -->
+ <hr>
+ <h2><!-- TMPL_IF name="view_definition" -->View:<!-- TMPL_ELSE -->Table:<!-- /TMPL_IF -->
+ <!-- TMPL_IF name="number_of_schemas" -->
+ <a href="#<!-- TMPL_VAR ESCAPE="URL" name="schema_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="schema" --></a>.<!-- /TMPL_IF name="number_of_schemas" --><a name="<!-- TMPL_VAR ESCAPE="URL" name="table_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="table" --></a>
+ </h2>
+ <!-- TMPL_IF name="table_comment" -->
+ <p><!-- TMPL_VAR ESCAPE="HTML" name="table_comment" --></p>
+ <!-- /TMPL_IF name="table_comment" -->
+
+
+ <table width="100%" cellspacing="0" cellpadding="3">
+ <caption><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="table" --> Structure</caption>
+ <tr>
+ <th>F-Key</th>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+ <!-- TMPL_LOOP name="columns" -->
+ <tr class="<!-- TMPL_IF name="__odd__" -->tr0<!-- tmpl_else name="__odd__" -->tr1<!-- /TMPL_IF name="__odd__" -->">
+ <td>
+ <!-- TMPL_LOOP name="column_constraints" -->
+ <!-- TMPL_IF name="column_fk" -->
+ <a href="#<!-- TMPL_VAR ESCAPE="URL" name="column_fk_sgmlid" -->"><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="column_fk_schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="column_fk_table" -->.<!-- TMPL_VAR ESCAPE="HTML" name="column_fk_colnum" --><!-- TMPL_IF name="column_fk_keygroup" -->#<!-- TMPL_VAR name="column_fk_keygroup" --><!-- /TMPL_IF name="column_fk_keygroup" --></a>
+ <!-- /TMPL_IF name="column_fk" -->
+ <!-- /TMPL_LOOP name="column_constraints" -->
+ </td>
+ <td><!-- TMPL_VAR ESCAPE="HTML" name="column" --></td>
+ <td><!-- TMPL_VAR ESCAPE="HTML" name="column_type" --></td>
+ <td><i>
+ <!-- TMPL_LOOP name="column_constraints" -->
+ <!-- TMPL_IF name="column_primary_key" -->PRIMARY KEY
+ <!-- /TMPL_IF name="column_primary_key" -->
+
+ <!-- TMPL_IF name="column_unique" -->
+ UNIQUE<!-- TMPL_IF name="column_unique_keygroup" -->#<!-- TMPL_VAR name="column_unique_keygroup" --><!-- /TMPL_IF name="column_unique_keygroup" -->
+ <!-- /TMPL_IF name="column_unique" -->
+ <!-- /TMPL_LOOP name="column_constraints" -->
+
+ <!-- TMPL_IF name="column_constraint_notnull" -->NOT NULL<!-- /TMPL_IF name="column_constraint_notnull" -->
+ <!-- TMPL_IF name="column_default" -->DEFAULT <!-- TMPL_VAR ESCAPE="HTML" name="column_default" --><!-- /TMPL_IF name="column_default" -->
+ </i>
+ <!-- TMPL_IF name="column_comment" --><br><br><!-- TMPL_VAR ESCAPE="HTML" name="column_comment" --><!-- /TMPL_IF name="column_comment" -->
+ </td>
+ </tr>
+ <!-- /TMPL_LOOP name="columns" -->
+ </table>
+
+ <!-- Inherits -->
+ <!-- TMPL_IF name="inherits" -->
+ <p>Table <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="table" --> Inherits
+ <!-- TMPL_LOOP name="inherits" -->
+ <!-- TMPL_VAR name="index_name" --> <!-- TMPL_VAR name="index_definition" -->
+ <a href="#<!-- TMPL_VAR ESCAPE="URL" name="parent_sgmlid" -->"><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="parent_schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="parent_table" --></a>,
+ <!-- /TMPL_LOOP name="inherits" -->
+ </p>
+ <!-- /TMPL_IF name="inherits" -->
+
+ <!-- TMPL_UNLESS name="view_definition" -->
+ <!-- TMPL_IF name="stats_enabled" -->
+ <p>&nbsp;</p>
+ <table width="100%" cellspacing="0" cellpadding="3">
+ <caption>Statistics</caption>
+ <tr>
+ <th>Total Space (disk usage)</th>
+ <th>Tuple Count</th>
+ <th>Active Space</th>
+ <th>Dead Space</th>
+ <th>Free Space</th>
+ </tr>
+ <tr class="tr0">
+ <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_table_bytes" --></td>
+ <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_tuple_count" --></td>
+ <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_tuple_bytes" --></td>
+ <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_dead_bytes" --></td>
+ <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_free_bytes" --></td>
+ </tr>
+ </table>
+ <!-- /TMPL_IF name="stats_enabled" -->
+ <!-- /TMPL_UNLESS name="view_definition" -->
+
+ <!-- Constraint List -->
+ <!-- TMPL_IF name="constraints" -->
+ <p>&nbsp;</p>
+ <table width="100%" cellspacing="0" cellpadding="3">
+ <caption><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="table" --> Constraints</caption>
+ <tr>
+ <th>Name</th>
+ <th>Constraint</th>
+ </tr>
+ <!-- TMPL_LOOP name="constraints" -->
+ <tr class="<!-- TMPL_IF name="__odd__" -->tr0<!-- TMPL_ELSE name="__odd__" -->tr1<!-- /TMPL_IF name="__odd__" -->">
+ <td><!-- TMPL_VAR ESCAPE="HTML" name="constraint_name" --></td>
+ <td><!-- TMPL_VAR ESCAPE="HTML" name="constraint" --></td>
+ </tr>
+ <!-- /TMPL_LOOP name="constraints" -->
+ </table>
+ <!-- /TMPL_IF name="constraints" -->
+
+ <!-- Foreign Key Discovery -->
+ <!-- TMPL_IF name="fk_schemas" -->
+ <p>Tables referencing this one via Foreign Key Constraints:</p>
+ <!-- TMPL_LOOP name="fk_schemas" -->
+ <ul>
+ <li><a href="#<!-- TMPL_VAR ESCAPE="URL" name="fk_sgmlid" -->"><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_table" --></a></li>
+ </ul>
+ <!-- /TMPL_LOOP name="fk_schemas" -->
+ <!-- /TMPL_IF name="fk_schemas" -->
+
+ <!-- Indexes -->
+ <!-- TMPL_LOOP name="indexes" -->
+ <!-- TMPL_VAR name="index_name" --> <!-- TMPL_VAR name="index_definition" -->
+ <!-- /TMPL_LOOP name="indexes" -->
+
+ <!-- View Definition -->
+ <!-- TMPL_IF name="view_definition" -->
+ <pre><!-- TMPL_VAR ESCAPE="HTML" name="view_definition" --></pre>
+ <!-- /TMPL_IF name="view_definition" -->
+
+ <!-- List off permissions -->
+ <!-- TMPL_IF name="permissions" -->
+ <p>&nbsp;</p>
+ <table width="100%" cellspacing="0" cellpadding="3">
+ <caption>Permissions which apply to <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="table" --></caption>
+ <tr>
+ <th>User</th>
+ <th><center>Select</center></th>
+ <th><center>Insert</center></th>
+ <th><center>Update</center></th>
+ <th><center>Delete</center></th>
+ <th><center>Reference</center></th>
+ <th><center>Rule</center></th>
+ <th><center>Trigger</center></th>
+ </tr>
+ <!-- TMPL_LOOP name="permissions" -->
+ <tr class="<!-- TMPL_IF name="__odd__" -->tr0<!-- tmpl_else name="__odd__" -->tr1<!-- /TMPL_IF name="__odd__" -->">
+ <td><!-- TMPL_VAR ESCAPE="HTML" name="user" --></td>
+ <td><!-- TMPL_IF name="select" --><center>&diams;</center><!-- /TMPL_IF name="select" --></td>
+ <td><!-- TMPL_IF name="insert" --><center>&diams;</center><!-- /TMPL_IF name="insert" --></td>
+ <td><!-- TMPL_IF name="update" --><center>&diams;</center><!-- /TMPL_IF name="update" --></td>
+ <td><!-- TMPL_IF name="delete" --><center>&diams;</center><!-- /TMPL_IF name="delete" --></td>
+ <td><!-- TMPL_IF name="references" --><center>&diams;</center><!-- /TMPL_IF name="references" --></td>
+ <td><!-- TMPL_IF name="rule" --><center>&diams;</center><!-- /TMPL_IF name="rule" --></td>
+ <td><!-- TMPL_IF name="trigger" --><center>&diams;</center><!-- /TMPL_IF name="trigger" --></td>
+ </tr>
+ <!-- /TMPL_LOOP name="permissions" -->
+ </table>
+ <!-- /TMPL_IF name="permissions" -->
+
+ <p>
+ <a href="#index">Index</a> -
+ <a href="#<!-- TMPL_VAR ESCAPE="URL" name="schema_sgmlid" -->">Schema <!-- TMPL_VAR ESCAPE="HTML" name="schema" --></a>
+ </p>
+ <!-- /TMPL_LOOP name="tables" -->
+
+ <!-- We've gone through the table structure, now lets take a look at user functions -->
+ <!-- TMPL_LOOP name="functions" -->
+ <hr>
+ <h2>Function:
+ <a href="#<!-- TMPL_VAR ESCAPE="HTML" name="schema_sgmlid" -->"><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" --></a>.<!-- /TMPL_IF name="number_of_schemas" --><a name="<!-- TMPL_VAR ESCAPE="URL" name="function_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="function" --></a>
+ </h2>
+<h3>Returns: <!-- TMPL_VAR ESCAPE="HTML" name="function_returns" --></h3>
+<h3>Language: <!-- TMPL_VAR ESCAPE="HTML" name="function_language" --></h3>
+ <!-- TMPL_IF name="function_comment" --><p><!-- TMPL_VAR ESCAPE="HTML" name="function_comment" --></p><!-- /TMPL_IF name="function_comment" -->
+ <pre><!-- TMPL_IF name="function_source" --><!-- TMPL_VAR ESCAPE="HTML" name="function_source" --><!-- /TMPL_IF name="function_source" --></pre>
+ <!-- /TMPL_LOOP name="functions" -->
+
+<!-- /TMPL_LOOP name="schemas" -->
+<p class="w3ref">Generated by <a href="http://www.rbt.ca/autodoc/">PostgreSQL Autodoc</a></p>
+<p class="w3ref"><a href="http://validator.w3.org/check/referer">W3C HTML 4.01 Strict</a></p>
+</body></html>
diff --git a/postgresql_autodoc/install-sh b/postgresql_autodoc/install-sh
new file mode 100755
index 0000000..398a88e
--- /dev/null
+++ b/postgresql_autodoc/install-sh
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ :
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=$mkdirprog
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ :
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ :
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ :
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+ '
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ :
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ :
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/postgresql_autodoc/neato.tmpl b/postgresql_autodoc/neato.tmpl
new file mode 100644
index 0000000..b21e067
--- /dev/null
+++ b/postgresql_autodoc/neato.tmpl
@@ -0,0 +1,22 @@
+digraph g {
+node [ fontsize = "10", shape = record ];
+edge [];
+<TMPL_LOOP name="schemas"><TMPL_LOOP name="tables"><TMPL_UNLESS
+name="view_definition">
+"<TMPL_IF name="number_of_schemas"><TMPL_VAR
+name="schema_dot">.</TMPL_IF name="number_of_schemas"><TMPL_VAR
+name="table_dot">" [shape = record, label = "{<col0> \N| <TMPL_LOOP
+name="columns"><TMPL_VAR name="column_dot">: <TMPL_VAR
+name="column_type">\l</TMPL_LOOP name="columns">}" ];
+</TMPL_UNLESS name="view_definition"></TMPL_LOOP
+name="tables"></TMPL_LOOP name="schemas">
+<TMPL_LOOP name="fk_links">
+"<TMPL_IF name="number_of_schemas"><TMPL_VAR
+name="handle0_schema">.</TMPL_IF name="number_of_schemas"><TMPL_VAR
+name="handle0_name">" -> "<TMPL_IF name="number_of_schemas"><TMPL_VAR
+name="handle1_schema">.</TMPL_IF name="number_of_schemas"><TMPL_VAR
+name="handle1_name">" [label="<TMPL_VAR
+name="fk_link_name_dot">"];</TMPL_LOOP name="fk_links">
+}
+
+
diff --git a/postgresql_autodoc/postgresql_autodoc b/postgresql_autodoc/postgresql_autodoc
new file mode 100755
index 0000000..503a8c5
--- /dev/null
+++ b/postgresql_autodoc/postgresql_autodoc
@@ -0,0 +1,1907 @@
+#!/usr/bin/perl
+# -- # -*- Perl -*-w
+# $Header: /cvsroot/autodoc/autodoc/postgresql_autodoc.pl,v 1.21 2008/03/12 19:00:56 rbt Exp $
+# Imported 1.22 2002/02/08 17:09:48 into sourceforge
+
+# Postgres Auto-Doc Version 1.31
+
+# License
+# -------
+# Copyright (c) 2001-2007, Rod Taylor
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+#
+# 3. Neither the name of the InQuent Technologies Inc. nor the names
+# of its contributors may be used to endorse or promote products
+# derived from this software without specific prior written
+# permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD
+# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# About Project
+# -------------
+# Various details about the project and related items can be found at
+# the website
+#
+# http://www.rbt.ca/autodoc/
+
+use strict;
+use warnings;
+
+use DBI;
+use Fcntl;
+
+# Allows file templates
+use HTML::Template;
+
+# Allow reading a password from stdin
+use Term::ReadKey;
+
+sub main($) {
+ my ($ARGV) = @_;
+
+ my %db;
+
+ # The templates path
+ # /usr/local/share/postgresql_autodoc will be replaced by make in the build phase
+ my $template_path = '/usr/local/share/postgresql_autodoc';
+
+ # Setup the default connection variables based on the environment
+ my $dbuser = $ENV{'PGUSER'};
+ $dbuser ||= $ENV{'USER'};
+
+ my $database = $ENV{'PGDATABASE'};
+ $database ||= $dbuser;
+
+ my $dbhost = $ENV{'PGHOST'};
+ $dbhost ||= "";
+
+ my $dbport = $ENV{'PGPORT'};
+ $dbport ||= "";
+
+ # Determine whether we need a password to connect
+ my $needpass = 0;
+
+ my $dbpass = "";
+ my $output_filename_base = $database;
+
+ # Tracking variables
+ my $dbisset = 0;
+ my $fileisset = 0;
+
+ my $only_schema;
+
+ my $table_out;
+
+ my $wanted_output = undef; # means all types
+
+ my $statistics = 0;
+
+ # Fetch base and dirnames. Useful for Usage()
+ my $basename = $0;
+ my $dirname = $0;
+ $basename =~ s|^.*/([^/]+)$|$1|;
+ $dirname =~ s|^(.*)/[^/]+$|$1|;
+
+ # If template_path isn't defined, lets set it ourselves
+ $template_path = $dirname if ( !defined($template_path) );
+
+ for ( my $i = 0 ; $i <= $#ARGV ; $i++ ) {
+ ARGPARSE: for ( $ARGV[$i] ) {
+
+ # Set the database
+ /^-d$/ && do {
+ $database = $ARGV[ ++$i ];
+ $dbisset = 1;
+ if ( !$fileisset ) {
+ $output_filename_base = $database;
+ }
+ last;
+ };
+
+ # Set the user
+ /^-[uU]$/ && do {
+ $dbuser = $ARGV[ ++$i ];
+ if ( !$dbisset ) {
+ $database = $dbuser;
+ if ( !$fileisset ) {
+ $output_filename_base = $database;
+ }
+ }
+ last;
+ };
+
+ # Set the hostname
+ /^-h$/ && do { $dbhost = $ARGV[ ++$i ]; last; };
+
+ # Set the Port
+ /^-p$/ && do { $dbport = $ARGV[ ++$i ]; last; };
+
+ # Set the users password
+ /^--password=/ && do {
+ $dbpass = $ARGV[$i];
+ $dbpass =~ s/^--password=//g;
+ last;
+ };
+
+ # Make sure we get a password before attempting to conenct
+ /^--password$/ && do {
+ $needpass = 1;
+ last;
+ };
+
+ # Set the base of the filename. The extensions pulled
+ # from the templates will be appended to this name
+ /^-f$/ && do {
+ $output_filename_base = $ARGV[ ++$i ];
+ $fileisset = 1;
+ last;
+ };
+
+ # Set the template directory explicitly
+ /^(-l|--library)$/ && do {
+ $template_path = $ARGV[ ++$i ];
+ last;
+ };
+
+ # Set the output type
+ /^(-t|--type)$/ && do {
+ $wanted_output = $ARGV[ ++$i ];
+ last;
+ };
+
+ # User has requested a single schema dump and provided a pattern
+ /^(-s|--schema)$/ && do {
+ $only_schema = $ARGV[ ++$i ];
+ last;
+ };
+
+ # One might dump a table's set (comma-separated) or just one
+ # If dumping a set of specific tables do NOT dump out the functions
+ # in this database. Generates noise in the output
+ # that most likely isn't wanted. Check for $table_out around the
+ # function gathering location.
+ /^--table=/ && do {
+ my $some_table = $ARGV[$i];
+ $some_table =~ s/^--table=//g;
+
+ my @tables_in = split( ',', $some_table );
+ sub single_quote;
+ $table_out = join( ',', map( single_quote, @tables_in ) );
+
+ last;
+ };
+
+ # Check to see if Statistics have been requested
+ /^--statistics$/ && do {
+ $statistics = 1;
+ last;
+ };
+
+ # Help is wanted, redirect user to usage()
+ /^-\?$/ && do { usage( $basename, $database, $dbuser ); last; };
+ /^--help$/ && do { usage( $basename, $database, $dbuser ); last; };
+ }
+ }
+
+ # If no arguments have been provided, connect to the database anyway but
+ # inform the user of what we're doing.
+ if ( $#ARGV <= 0 ) {
+ print <<Msg
+No arguments set. Use '$basename --help' for help
+
+Connecting to database '$database' as user '$dbuser'
+Msg
+ ;
+ }
+
+ # If needpass has been set but no password was provided, prompt the user
+ # for a password.
+ if ( $needpass and not $dbpass ) {
+ print "Password: ";
+ ReadMode 'noecho';
+ $dbpass = ReadLine 0;
+ chomp $dbpass;
+ ReadMode 'normal';
+ print "\n";
+ }
+
+ # Database Connection
+ my $dsn = "dbi:Pg:dbname=$database";
+ $dsn .= ";host=$dbhost" if ( "$dbhost" ne "" );
+ $dsn .= ";port=$dbport" if ( "$dbport" ne "" );
+
+ info_collect( [ $dsn, $dbuser, $dbpass ],
+ \%db, $database, $only_schema, $statistics, $table_out );
+
+ # Write out *ALL* templates
+ write_using_templates( \%db, $database, $statistics, $template_path,
+ $output_filename_base, $wanted_output );
+} ## end sub main($)
+
+##
+# info_collect
+#
+# Pull out all of the applicable information about a specific database
+sub info_collect {
+ my ( $dbConnect, $db, $database, $only_schema, $statistics, $table_out ) =
+ @_;
+
+ my $dbh = DBI->connect( @{$dbConnect} )
+ or triggerError("Unable to connect due to: $DBI::errstr");
+
+ $dbh->do("set client_encoding to 'UTF-8'")
+ or triggerError("could not set client_encoding to UTF-8: $DBI::errstr");
+
+ my %struct;
+ $db->{$database}{'STRUCT'} = \%struct;
+ my $struct = $db->{$database}{'STRUCT'};
+
+ # PostgreSQL's version is used to determine what queries are required
+ # to retrieve a given information set.
+ if ( $dbh->{pg_server_version} < 70300 ) {
+ die("PostgreSQL 7.3 and later are supported");
+ }
+
+ # Ensure we only retrieve information for the requested schemas.
+ #
+ # system_schema -> The primary system schema for a database.
+ # Public is used for verions prior to 7.3
+ #
+ # system_schema_list -> The list of schemas which we are not supposed
+ # to gather information for.
+ # TODO: Merge with system_schema in array form.
+ #
+ # schemapattern -> The schema the user provided as a command
+ # line option.
+ my $schemapattern = '^';
+ my $system_schema = 'pg_catalog';
+ my $system_schema_list =
+ 'pg_catalog|pg_toast|pg_temp_[0-9]+|information_schema';
+ if ( defined($only_schema) ) {
+ $schemapattern = '^' . $only_schema . '$';
+ }
+
+ #
+ # List of queries which are used to gather information from the
+ # database. The queries differ based on version but should
+ # provide similar output. At some point it should be safe to remove
+ # support for older database versions.
+ #
+
+ # Fetch the description of the database
+ my $sql_Database = q{
+ SELECT pg_catalog.obj_description(oid, 'pg_database') as comment
+ FROM pg_catalog.pg_database
+ WHERE datname = '$database';
+ };
+
+ # Pull out a list of tables, views and special structures.
+ my $sql_Tables = qq{
+ SELECT nspname as namespace
+ , relname as tablename
+ , pg_catalog.pg_get_userbyid(relowner) AS tableowner
+ , relhasindex as hasindexes
+ , relhasrules as hasrules
+ , reltriggers as hastriggers
+ , pg_class.oid
+ , pg_catalog.obj_description(pg_class.oid, 'pg_class') as table_description
+ , relacl
+ , CASE
+ WHEN relkind = 'r' THEN
+ 'table'
+ WHEN relkind = 's' THEN
+ 'special'
+ ELSE
+ 'view'
+ END as reltype
+ , CASE
+ WHEN relkind = 'v' THEN
+ pg_get_viewdef(pg_class.oid)
+ ELSE
+ NULL
+ END as view_definition
+ FROM pg_catalog.pg_class
+ JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid)
+ WHERE relkind IN ('r', 's', 'v')
+ AND nspname !~ '$system_schema_list'
+ AND nspname ~ '$schemapattern'
+ };
+ $sql_Tables .= qq{ AND relname IN ($table_out)} if defined($table_out);
+
+ # - uses pg_class.oid
+ my $sql_Columns = q{
+ SELECT attname as column_name
+ , attlen as column_length
+ , CASE
+ WHEN pg_type.typname = 'int4'
+ AND EXISTS (SELECT TRUE
+ FROM pg_catalog.pg_depend
+ JOIN pg_catalog.pg_class ON (pg_class.oid = objid)
+ WHERE refobjsubid = attnum
+ AND refobjid = attrelid
+ AND relkind = 'S') THEN
+ 'serial'
+ WHEN pg_type.typname = 'int8'
+ AND EXISTS (SELECT TRUE
+ FROM pg_catalog.pg_depend
+ JOIN pg_catalog.pg_class ON (pg_class.oid = objid)
+ WHERE refobjsubid = attnum
+ AND refobjid = attrelid
+ AND relkind = 'S') THEN
+ 'bigserial'
+ ELSE
+ pg_catalog.format_type(atttypid, atttypmod)
+ END as column_type
+ , CASE
+ WHEN attnotnull THEN
+ cast('NOT NULL' as text)
+ ELSE
+ cast('' as text)
+ END as column_null
+ , CASE
+ WHEN pg_type.typname IN ('int4', 'int8')
+ AND EXISTS (SELECT TRUE
+ FROM pg_catalog.pg_depend
+ JOIN pg_catalog.pg_class ON (pg_class.oid = objid)
+ WHERE refobjsubid = attnum
+ AND refobjid = attrelid
+ AND relkind = 'S') THEN
+ NULL
+ ELSE
+ adsrc
+ END as column_default
+ , pg_catalog.col_description(attrelid, attnum) as column_description
+ , attnum
+ FROM pg_catalog.pg_attribute
+ JOIN pg_catalog.pg_type ON (pg_type.oid = atttypid)
+ LEFT JOIN pg_catalog.pg_attrdef ON ( attrelid = adrelid
+ AND attnum = adnum)
+ WHERE attnum > 0
+ AND attisdropped IS FALSE
+ AND attrelid = ?;
+ };
+
+ my $sql_Table_Statistics;
+ if ( $statistics == 1 ) {
+ if ( $dbh->{pg_server_version} <= 70300 ) {
+ triggerError(
+ "Table statistics supported on PostgreSQL 7.4 and later.\n"
+ . "Remove --statistics flag and try again." );
+ }
+
+ $sql_Table_Statistics = q{
+ SELECT table_len
+ , tuple_count
+ , tuple_len
+ , CAST(tuple_percent AS numeric(20,2)) AS tuple_percent
+ , dead_tuple_count
+ , dead_tuple_len
+ , CAST(dead_tuple_percent AS numeric(20,2)) AS dead_tuple_percent
+ , CAST(free_space AS numeric(20,2)) AS free_space
+ , CAST(free_percent AS numeric(20,2)) AS free_percent
+ FROM pgstattuple(CAST(? AS oid));
+ };
+ }
+
+ my $sql_Indexes = q{
+ SELECT schemaname
+ , tablename
+ , indexname
+ , substring( indexdef
+ FROM position('(' IN indexdef) + 1
+ FOR length(indexdef) - position('(' IN indexdef) - 1
+ ) AS indexdef
+ FROM pg_catalog.pg_indexes
+ WHERE substring(indexdef FROM 8 FOR 6) != 'UNIQUE'
+ AND schemaname = ?
+ AND tablename = ?;
+ };
+
+ my $sql_Inheritance = qq{
+ SELECT parnsp.nspname AS par_schemaname
+ , parcla.relname AS par_tablename
+ , chlnsp.nspname AS chl_schemaname
+ , chlcla.relname AS chl_tablename
+ FROM pg_catalog.pg_inherits
+ JOIN pg_catalog.pg_class AS chlcla ON (chlcla.oid = inhrelid)
+ JOIN pg_catalog.pg_namespace AS chlnsp ON (chlnsp.oid = chlcla.relnamespace)
+ JOIN pg_catalog.pg_class AS parcla ON (parcla.oid = inhparent)
+ JOIN pg_catalog.pg_namespace AS parnsp ON (parnsp.oid = parcla.relnamespace)
+ WHERE chlnsp.nspname = ?
+ AND chlcla.relname = ?
+ AND chlnsp.nspname ~ '$schemapattern'
+ AND parnsp.nspname ~ '$schemapattern';
+ };
+
+ # Fetch the list of PRIMARY and UNIQUE keys
+ my $sql_Primary_Keys = q{
+ SELECT conname AS constraint_name
+ , pg_catalog.pg_get_indexdef(d.objid) AS constraint_definition
+ , CASE
+ WHEN contype = 'p' THEN
+ 'PRIMARY KEY'
+ ELSE
+ 'UNIQUE'
+ END as constraint_type
+ FROM pg_catalog.pg_constraint AS c
+ JOIN pg_catalog.pg_depend AS d ON (d.refobjid = c.oid)
+ WHERE contype IN ('p', 'u')
+ AND deptype = 'i'
+ AND conrelid = ?;
+ };
+
+ # FOREIGN KEY fetch
+ #
+ # Don't return the constraint name if it was automatically generated by
+ # PostgreSQL. The $N (where N is an integer) is not a descriptive enough
+ # piece of information to be worth while including in the various outputs.
+ my $sql_Foreign_Keys = qq{
+ SELECT pg_constraint.oid
+ , pg_namespace.nspname AS namespace
+ , CASE WHEN substring(pg_constraint.conname FROM 1 FOR 1) = '\$' THEN ''
+ ELSE pg_constraint.conname
+ END AS constraint_name
+ , conkey AS constraint_key
+ , confkey AS constraint_fkey
+ , confrelid AS foreignrelid
+ FROM pg_catalog.pg_constraint
+ JOIN pg_catalog.pg_class ON (pg_class.oid = conrelid)
+ JOIN pg_catalog.pg_class AS pc ON (pc.oid = confrelid)
+ JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid)
+ JOIN pg_catalog.pg_namespace AS pn ON (pn.oid = pc.relnamespace)
+ WHERE contype = 'f'
+ AND conrelid = ?
+ AND pg_namespace.nspname ~ '$schemapattern'
+ AND pn.nspname ~ '$schemapattern';
+ };
+
+ my $sql_Foreign_Key_Arg = q{
+ SELECT attname AS attribute_name
+ , relname AS relation_name
+ , nspname AS namespace
+ FROM pg_catalog.pg_attribute
+ JOIN pg_catalog.pg_class ON (pg_class.oid = attrelid)
+ JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid)
+ WHERE attrelid = ?
+ AND attnum = ?;
+ };
+
+ # Fetch CHECK constraints
+ my $sql_Constraint;
+ if ( $dbh->{pg_server_version} >= 70400 ) {
+ $sql_Constraint = q{
+ SELECT pg_get_constraintdef(oid) AS constraint_source
+ , conname AS constraint_name
+ FROM pg_constraint
+ WHERE conrelid = ?
+ AND contype = 'c';
+ };
+ }
+ else {
+ $sql_Constraint = q{
+ SELECT 'CHECK ' || pg_catalog.substr(consrc, 2, length(consrc) - 2) AS constraint_source
+ , conname AS constraint_name
+ FROM pg_constraint
+ WHERE conrelid = ?
+ AND contype = 'c';
+ };
+ }
+
+ # Query for function information
+ my $sql_Function;
+ my $sql_FunctionArg;
+ if ( $dbh->{pg_server_version} >= 80000 ) {
+ $sql_Function = qq{
+ SELECT proname AS function_name
+ , nspname AS namespace
+ , lanname AS language_name
+ , pg_catalog.obj_description(pg_proc.oid, 'pg_proc') AS comment
+ , proargtypes AS function_args
+ , proargnames AS function_arg_names
+ , prosrc AS source_code
+ , proretset AS returns_set
+ , prorettype AS return_type
+ FROM pg_catalog.pg_proc
+ JOIN pg_catalog.pg_language ON (pg_language.oid = prolang)
+ JOIN pg_catalog.pg_namespace ON (pronamespace = pg_namespace.oid)
+ JOIN pg_catalog.pg_type ON (prorettype = pg_type.oid)
+ WHERE pg_namespace.nspname !~ '$system_schema_list'
+ AND pg_namespace.nspname ~ '$schemapattern'
+ AND proname != 'plpgsql_call_handler';
+ };
+
+ $sql_FunctionArg = q{
+ SELECT nspname AS namespace
+ , replace(pg_catalog.format_type(pg_type.oid, typtypmod)
+ , nspname ||'.'
+ , '') AS type_name
+ FROM pg_catalog.pg_type
+ JOIN pg_catalog.pg_namespace ON (pg_namespace.oid = typnamespace)
+ WHERE pg_type.oid = ?;
+ };
+ }
+ else {
+ $sql_Function = qq{
+ SELECT proname AS function_name
+ , nspname AS namespace
+ , lanname AS language_name
+ , pg_catalog.obj_description(pg_proc.oid, 'pg_proc') AS comment
+ , proargtypes AS function_args
+ , NULL AS function_arg_names
+ , prosrc AS source_code
+ , proretset AS returns_set
+ , prorettype AS return_type
+ FROM pg_catalog.pg_proc
+ JOIN pg_catalog.pg_language ON (pg_language.oid = prolang)
+ JOIN pg_catalog.pg_namespace ON (pronamespace = pg_namespace.oid)
+ JOIN pg_catalog.pg_type ON (prorettype = pg_type.oid)
+ WHERE pg_namespace.nspname !~ '$system_schema_list'
+ AND pg_namespace.nspname ~ '$schemapattern'
+ AND proname != 'plpgsql_call_handler';
+ };
+
+ $sql_FunctionArg = q{
+ SELECT nspname AS namespace
+ , replace(pg_catalog.format_type(pg_type.oid, typtypmod)
+ , nspname ||'.'
+ , '') AS type_name
+ FROM pg_catalog.pg_type
+ JOIN pg_catalog.pg_namespace ON (pg_namespace.oid = typnamespace)
+ WHERE pg_type.oid = ?;
+ };
+ }
+
+ # Fetch schema information.
+ my $sql_Schema = qq{
+ SELECT pg_catalog.obj_description(oid, 'pg_namespace') AS comment
+ , nspname as namespace
+ FROM pg_catalog.pg_namespace
+ WHERE pg_namespace.nspname !~ '$system_schema_list'
+ AND pg_namespace.nspname ~ '$schemapattern';
+ };
+
+ my $sth_Columns = $dbh->prepare($sql_Columns);
+ my $sth_Constraint = $dbh->prepare($sql_Constraint);
+ my $sth_Database = $dbh->prepare($sql_Database);
+ my $sth_Foreign_Keys = $dbh->prepare($sql_Foreign_Keys);
+ my $sth_Foreign_Key_Arg = $dbh->prepare($sql_Foreign_Key_Arg);
+ my $sth_Function = $dbh->prepare($sql_Function);
+ my $sth_FunctionArg = $dbh->prepare($sql_FunctionArg);
+ my $sth_Indexes = $dbh->prepare($sql_Indexes);
+ my $sth_Inheritance = $dbh->prepare($sql_Inheritance);
+ my $sth_Primary_Keys = $dbh->prepare($sql_Primary_Keys);
+ my $sth_Schema = $dbh->prepare($sql_Schema);
+ my $sth_Tables = $dbh->prepare($sql_Tables);
+ my $sth_Table_Statistics = $dbh->prepare($sql_Table_Statistics)
+ if ( $statistics == 1 );
+
+ # Fetch Database info
+ $sth_Database->execute();
+ my $dbinfo = $sth_Database->fetchrow_hashref;
+ if ( defined($dbinfo) ) {
+ $db->{$database}{'COMMENT'} = $dbinfo->{'comment'};
+ }
+
+ # Fetch tables and all things bound to tables
+ $sth_Tables->execute();
+ while ( my $tables = $sth_Tables->fetchrow_hashref ) {
+ my $reloid = $tables->{'oid'};
+ my $relname = $tables->{'tablename'};
+
+ my $schema = $tables->{'namespace'};
+
+ EXPRESSIONFOUND:
+
+ # Store permissions
+ my $acl = $tables->{'relacl'};
+
+ # Empty acl groups cause serious issues.
+ $acl ||= '';
+
+ # Strip array forming 'junk'.
+ $acl =~ s/^{//g;
+ $acl =~ s/}$//g;
+ $acl =~ s/"//g;
+
+ # Foreach acl
+ foreach ( split( /\,/, $acl ) ) {
+ my ( $user, $raw_permissions ) = split( /=/, $_ );
+
+ if ( defined($raw_permissions) ) {
+ if ( $user eq '' ) {
+ $user = 'PUBLIC';
+ }
+
+ # The section after the / is the user who granted the permissions
+ my ( $permissions, $granting_user ) =
+ split( /\//, $raw_permissions );
+
+ # Break down permissions to individual flags
+ if ( $permissions =~ /a/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'INSERT'} = 1;
+ }
+
+ if ( $permissions =~ /r/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'SELECT'} = 1;
+ }
+
+ if ( $permissions =~ /w/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'UPDATE'} = 1;
+ }
+
+ if ( $permissions =~ /d/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'DELETE'} = 1;
+ }
+
+ if ( $permissions =~ /R/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'RULE'} = 1;
+ }
+
+ if ( $permissions =~ /x/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'REFERENCES'} = 1;
+ }
+
+ if ( $permissions =~ /t/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'TRIGGER'} = 1;
+ }
+ }
+ }
+
+ # Primitive Stats, but only if requested
+ if ( $statistics == 1 and $tables->{'reltype'} eq 'table' ) {
+ $sth_Table_Statistics->execute($reloid);
+
+ my $stats = $sth_Table_Statistics->fetchrow_hashref;
+
+ $struct->{$schema}{'TABLE'}{$relname}{'TABLELEN'} =
+ $stats->{'table_len'};
+ $struct->{$schema}{'TABLE'}{$relname}{'TUPLECOUNT'} =
+ $stats->{'tuple_count'};
+ $struct->{$schema}{'TABLE'}{$relname}{'TUPLELEN'} =
+ $stats->{'tuple_len'};
+ $struct->{$schema}{'TABLE'}{$relname}{'DEADTUPLELEN'} =
+ $stats->{'dead_tuple_len'};
+ $struct->{$schema}{'TABLE'}{$relname}{'FREELEN'} =
+ $stats->{'free_space'};
+ }
+
+ # Store the relation type
+ $struct->{$schema}{'TABLE'}{$relname}{'TYPE'} = $tables->{'reltype'};
+
+ # Store table description
+ $struct->{$schema}{'TABLE'}{$relname}{'DESCRIPTION'} =
+ $tables->{'table_description'};
+
+ # Store the view definition
+ $struct->{$schema}{'TABLE'}{$relname}{'VIEW_DEF'} =
+ $tables->{'view_definition'};
+
+ # Store constraints
+ $sth_Constraint->execute($reloid);
+ while ( my $cols = $sth_Constraint->fetchrow_hashref ) {
+ my $constraint_name = $cols->{'constraint_name'};
+ $struct->{$schema}{'TABLE'}{$relname}{'CONSTRAINT'}
+ {$constraint_name} = $cols->{'constraint_source'};
+ }
+
+ $sth_Columns->execute($reloid);
+ my $i = 1;
+ while ( my $cols = $sth_Columns->fetchrow_hashref ) {
+ my $column_name = $cols->{'column_name'};
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'ORDER'} = $cols->{'attnum'};
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'PRIMARY KEY'} = 0;
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'FKTABLE'} = '';
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'TYPE'} = $cols->{'column_type'};
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'NULL'} = $cols->{'column_null'};
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'DESCRIPTION'} = $cols->{'column_description'};
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'DEFAULT'} = $cols->{'column_default'};
+ }
+
+ # Pull out both PRIMARY and UNIQUE keys based on the supplied query
+ # and the relation OID.
+ #
+ # Since there may be multiple UNIQUE indexes on a table, we append a
+ # number to the end of the the UNIQUE keyword which shows that they
+ # are a part of a related definition. I.e UNIQUE_1 goes with UNIQUE_1
+ #
+ $sth_Primary_Keys->execute($reloid);
+ my $unqgroup = 0;
+ while ( my $pricols = $sth_Primary_Keys->fetchrow_hashref ) {
+ my $index_type = $pricols->{'constraint_type'};
+ my $con = $pricols->{'constraint_name'};
+ my $indexdef = $pricols->{'constraint_definition'};
+
+ # Fetch the column list
+ my $column_list = $indexdef;
+ $column_list =~ s/.*\(([^)]+)\).*/$1/g;
+
+ # Split our column list and deal with all PRIMARY KEY fields
+ my @collist = split( ',', $column_list );
+
+ # Store the column number in the indextype field. Anything > 0
+ # indicates the column has this type of constraint applied to it.
+ my $column;
+ my $currentcol = $#collist + 1;
+ my $numcols = $#collist + 1;
+
+ # Bump group number if there are two or more columns
+ if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) {
+ $unqgroup++;
+ }
+
+ # Record the data to the structure.
+ while ( $column = pop(@collist) ) {
+ $column =~ s/\s$//;
+ $column =~ s/^\s//;
+ $column =~ s/^"//;
+ $column =~ s/"$//;
+
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'TYPE'} = $index_type;
+
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'COLNUM'} = $currentcol--;
+
+ # Record group number only when a multi-column
+ # constraint is involved
+ if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}
+ {'CON'}{$con}{'KEYGROUP'} = $unqgroup;
+ }
+ }
+ }
+
+ # FOREIGN KEYS like UNIQUE indexes can appear several times in
+ # a table in multi-column format. We use the same trick to
+ # record a numeric association to the foreign key reference.
+ $sth_Foreign_Keys->execute($reloid);
+ my $fkgroup = 0;
+ while ( my $forcols = $sth_Foreign_Keys->fetchrow_hashref ) {
+ my $column_oid = $forcols->{'oid'};
+ my $con = $forcols->{'constraint_name'};
+
+ # Declare variables for dataload
+ my @keylist;
+ my @fkeylist;
+ my $fschema;
+ my $ftable;
+
+ my $fkey = $forcols->{'constraint_fkey'};
+ my $keys = $forcols->{'constraint_key'};
+ my $frelid = $forcols->{'foreignrelid'};
+
+ # Since decent array support was not added until 7.4, and
+ # we want to support 7.3 as well, we parse the text version
+ # of the array by hand rather than combining this and
+ # Foreign_Key_Arg query into a single query.
+
+ my @fkeyset;
+ if ( ref $fkey eq 'ARRAY' ) {
+ @fkeyset = @{$fkey};
+ }
+ else { # DEPRECATED: DBD::Pg 1.49 and earlier
+ $fkey =~ s/^{//g;
+ $fkey =~ s/}$//g;
+ $fkey =~ s/"//g;
+ @fkeyset = split( /,/, $fkey );
+ }
+
+ my @keyset;
+ if ( ref $keys eq 'ARRAY' ) {
+ @keyset = @{$keys};
+ }
+ else { # DEPRECATED: DBD::Pg 1.49 and earlier
+ $keys =~ s/^{//g;
+ $keys =~ s/}$//g;
+ $keys =~ s/"//g;
+ @keyset = split( /,/, $keys );
+ }
+
+ # Convert the list of column numbers into column names for the
+ # local side.
+ foreach my $k (@keyset) {
+ $sth_Foreign_Key_Arg->execute( $reloid, $k );
+
+ my $row = $sth_Foreign_Key_Arg->fetchrow_hashref;
+
+ push( @keylist, $row->{'attribute_name'} );
+ }
+
+ # Convert the list of columns numbers into column names
+ # for the referenced side. Grab the table and namespace
+ # while we're here.
+ foreach my $k (@fkeyset) {
+ $sth_Foreign_Key_Arg->execute( $frelid, $k );
+
+ my $row = $sth_Foreign_Key_Arg->fetchrow_hashref;
+
+ push( @fkeylist, $row->{'attribute_name'} );
+ $fschema = $row->{'namespace'};
+ $ftable = $row->{'relation_name'};
+ }
+
+ # Deal with common catalog issues.
+ die "FKEY $con Broken -- fix your PostgreSQL installation"
+ if $#keylist != $#fkeylist;
+
+ # Load up the array based on the information discovered
+ # using the information retrieval methods above.
+ my $numcols = $#keylist + 1;
+ my $currentcol = $#keylist + 1;
+
+ # Bump group number if there are two or more columns involved
+ if ( $numcols >= 2 ) {
+ $fkgroup++;
+ }
+
+ # Record the foreign key to structure
+ while ( my $column = pop(@keylist)
+ and my $fkey = pop(@fkeylist) )
+ {
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'TYPE'} = 'FOREIGN KEY';
+
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'COLNUM'} = $currentcol--;
+
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'FKTABLE'} = $ftable;
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'FKSCHEMA'} = $fschema;
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'FK-COL NAME'} = $fkey;
+
+ # Record group number only when a multi-column
+ # constraint is involved
+ if ( $numcols >= 2 ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}
+ {'CON'}{$con}{'KEYGROUP'} = $fkgroup;
+ }
+ }
+ }
+
+ # Pull out index information
+ $sth_Indexes->execute( $schema, $relname );
+ while ( my $idx = $sth_Indexes->fetchrow_hashref ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'INDEX'}
+ { $idx->{'indexname'} } = $idx->{'indexdef'};
+ }
+
+ # Extract Inheritance information
+ $sth_Inheritance->execute( $schema, $relname );
+ while ( my $inherit = $sth_Inheritance->fetchrow_hashref ) {
+ my $parSch = $inherit->{'par_schemaname'};
+ my $parTab = $inherit->{'par_tablename'};
+ $struct->{$schema}{'TABLE'}{$relname}{'INHERIT'}{$parSch}{$parTab} =
+ 1;
+ }
+ }
+
+ # Function Handling
+ $sth_Function->execute();
+ while ( my $functions = $sth_Function->fetchrow_hashref and not $table_out )
+ {
+ my $functionname = $functions->{'function_name'} . '( ';
+ my $schema = $functions->{'namespace'};
+ my $comment = $functions->{'comment'};
+ my $functionargs = $functions->{'function_args'};
+ my @types = split( ' ', $functionargs );
+ my $count = 0;
+
+ # Pre-setup argument names when available.
+ my $argnames = $functions->{'function_arg_names'};
+ my @names;
+
+ if ( defined($argnames) ) {
+ $argnames =~ s/{(.*)}/$1/;
+ @names = split( ',', $argnames );
+ }
+
+ # Setup full argument types -- including the name prefix
+ foreach my $type (@types) {
+ $sth_FunctionArg->execute($type);
+
+ my $hash = $sth_FunctionArg->fetchrow_hashref;
+
+ if ( $count > 0 ) {
+ $functionname .= ', ';
+ }
+
+ if ( scalar(@names) > 0 ) {
+ $functionname .= $names[$count] . ' ';
+ }
+
+ if ( $hash->{'namespace'} ne $system_schema ) {
+ $functionname .= $hash->{'namespace'} . '.';
+ }
+ $functionname .= $hash->{'type_name'};
+
+ $count++;
+ }
+ $functionname .= ' )';
+
+ my $ret_type = $functions->{'returns_set'} ? 'SET OF ' : '';
+ $sth_FunctionArg->execute( $functions->{'return_type'} );
+ my $rhash = $sth_FunctionArg->fetchrow_hashref;
+ $ret_type .= $rhash->{'type_name'};
+
+ $struct->{$schema}{'FUNCTION'}{$functionname}{'COMMENT'} = $comment;
+ $struct->{$schema}{'FUNCTION'}{$functionname}{'SOURCE'} =
+ $functions->{'source_code'};
+ $struct->{$schema}{'FUNCTION'}{$functionname}{'LANGUAGE'} =
+ $functions->{'language_name'};
+ $struct->{$schema}{'FUNCTION'}{$functionname}{'RETURNS'} = $ret_type;
+ }
+
+ # Deal with the Schema
+ $sth_Schema->execute();
+ while ( my $schema = $sth_Schema->fetchrow_hashref ) {
+ my $comment = $schema->{'comment'};
+ my $namespace = $schema->{'namespace'};
+
+ $struct->{$namespace}{'SCHEMA'}{'COMMENT'} = $comment;
+ }
+
+ $sth_Columns->finish();
+ $sth_Constraint->finish();
+ $sth_Database->finish();
+ $sth_Foreign_Keys->finish();
+ $sth_Foreign_Key_Arg->finish();
+ $sth_Function->finish();
+ $sth_FunctionArg->finish();
+ $sth_Indexes->finish();
+ $sth_Inheritance->finish();
+ $sth_Primary_Keys->finish();
+ $sth_Schema->finish();
+ $sth_Tables->finish();
+ $sth_Table_Statistics->finish()
+ if ( $statistics == 1 );
+
+ $dbh->disconnect;
+
+} ## end sub info_collect($$$$$)
+
+#####
+# write_using_templates
+#
+# Generate structure that HTML::Template requires out of the
+# $struct for table related information, and $struct for
+# the schema and function information
+sub write_using_templates($$$$$) {
+ my ( $db, $database, $statistics, $template_path, $output_filename_base,
+ $wanted_output )
+ = @_;
+ my $struct = $db->{$database}{'STRUCT'};
+
+ my @schemas;
+
+ # Start at 0, increment to 1 prior to use.
+ my $object_id = 0;
+ my %tableids;
+ foreach my $schema ( sort keys %{$struct} ) {
+ my @tables;
+ foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) {
+
+ # Column List
+ my @columns;
+ foreach my $column (
+ sort {
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a}
+ {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table}
+ {'COLUMN'}{$b}{'ORDER'}
+ } keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} }
+ )
+ {
+ my $inferrednotnull = 0;
+
+ # Have a shorter default for places that require it
+ my $shortdefault =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'DEFAULT'};
+ $shortdefault =~ s/^(.{17}).{5,}(.{5})$/$1 ... $2/g
+ if ( defined($shortdefault) );
+
+ # Deal with column constraints
+ my @colconstraints;
+ foreach my $con (
+ sort keys %{
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}
+ }
+ )
+ {
+ if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'TYPE'} eq 'UNIQUE' )
+ {
+ my $unq =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'TYPE'};
+ my $unqcol =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'COLNUM'};
+ my $unqgroup =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'KEYGROUP'};
+
+ push @colconstraints,
+ {
+ column_unique => $unq,
+ column_unique_colnum => $unqcol,
+ column_unique_keygroup => $unqgroup,
+ };
+ }
+ elsif (
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'TYPE'} eq 'PRIMARY KEY' )
+ {
+ $inferrednotnull = 1;
+ push @colconstraints,
+ { column_primary_key => 'PRIMARY KEY', };
+ }
+ elsif (
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY' )
+ {
+ my $fksgmlid = sgml_safe_id(
+ join( '.',
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+ {$column}{'CON'}{$con}{'FKSCHEMA'},
+ $struct->{$schema}{'TABLE'}{$table}{'TYPE'},
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+ {$column}{'CON'}{$con}{'FKTABLE'} )
+ );
+
+ my $fkgroup =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'KEYGROUP'};
+ my $fktable =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'FKTABLE'};
+ my $fkcol =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'FK-COL NAME'};
+ my $fkschema =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'FKSCHEMA'};
+
+ push @colconstraints,
+ {
+ column_fk => 'FOREIGN KEY',
+ column_fk_colnum => $fkcol,
+ column_fk_keygroup => $fkgroup,
+ column_fk_schema => $fkschema,
+ column_fk_schema_dbk => docbook($fkschema),
+ column_fk_schema_dot => graphviz($fkschema),
+ column_fk_sgmlid => $fksgmlid,
+ column_fk_table => $fktable,
+ column_fk_table_dbk => docbook($fktable),
+ };
+
+ # only have the count if there is more than 1 schema
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $colconstraints[-1]{"number_of_schemas"} =
+ scalar( keys %{$struct} );
+ }
+ }
+ }
+
+ # Generate the Column array
+ push @columns, {
+ column => $column,
+ column_dbk => docbook($column),
+ column_dot => graphviz($column),
+ column_default =>
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'DEFAULT'},
+ column_default_dbk => docbook(
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'DEFAULT'}
+ ),
+ column_default_short => $shortdefault,
+ column_default_short_dbk => docbook($shortdefault),
+
+ column_comment =>
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'DESCRIPTION'},
+ column_comment_dbk => docbook(
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'DESCRIPTION'}
+ ),
+
+ column_number =>
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'ORDER'},
+
+ column_type =>
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'TYPE'},
+ column_type_dbk => docbook(
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'TYPE'}
+ ),
+ column_type_dot => graphviz(
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'TYPE'}
+ ),
+
+ column_constraints => \@colconstraints,
+ };
+
+ if ( $inferrednotnull == 0 ) {
+ $columns[-1]{"column_constraint_notnull"} =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'NULL'};
+ }
+ }
+
+ # Constraint List
+ my @constraints;
+ foreach my $constraint (
+ sort
+ keys %{ $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} }
+ )
+ {
+ my $shortcon =
+ $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'}
+ {$constraint};
+ $shortcon =~ s/^(.{30}).{5,}(.{5})$/$1 ... $2/g;
+ push @constraints,
+ {
+ constraint =>
+ $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'}
+ {$constraint},
+ constraint_dbk => docbook(
+ $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'}
+ {$constraint}
+ ),
+ constraint_name => $constraint,
+ constraint_name_dbk => docbook($constraint),
+ constraint_short => $shortcon,
+ constraint_short_dbk => docbook($shortcon),
+ table => $table,
+ table_dbk => docbook($table),
+ table_dot => graphviz($table),
+ };
+ }
+
+ # Index List
+ my @indexes;
+ foreach my $index (
+ sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INDEX'} } )
+ {
+ push @indexes,
+ {
+ index_definition =>
+ $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index},
+ index_definition_dbk => docbook(
+ $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index}
+ ),
+ index_name => $index,
+ index_name_dbk => docbook($index),
+ table => $table,
+ table_dbk => docbook($table),
+ table_dot => graphviz($table),
+ schema => $schema,
+ schema_dbk => docbook($schema),
+ schema_dot => graphviz($schema),
+ };
+ }
+
+ my @inherits;
+ foreach my $inhSch (
+ sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'} } )
+ {
+ foreach my $inhTab (
+ sort keys
+ %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'}{$inhSch} }
+ )
+ {
+ push @inherits,
+ {
+ table => $table,
+ table_dbk => docbook($table),
+ table_dot => graphviz($table),
+ schema => $schema,
+ schema_dbk => docbook($schema),
+ schema_dot => graphviz($schema),
+ sgmlid =>
+ sgml_safe_id( join( '.', $schema, 'table', $table ) ),
+ parent_sgmlid => sgml_safe_id(
+ join( '.', $inhSch, 'table', $inhTab )
+ ),
+ parent_table => $inhTab,
+ parent_table_dbk => docbook($inhTab),
+ parent_table_dot => graphviz($inhTab),
+ parent_schema => $inhSch,
+ parent_schema_dbk => docbook($inhSch),
+ parent_schema_dot => graphviz($inhSch),
+ };
+ }
+ }
+
+ # Foreign Key Discovery
+ #
+ # $lastmatch is used to ensure that we only supply a result a
+ # single time and not once for each link found. Since the
+ # loops are sorted, we only need to track the last element, and
+ # not all supplied elements.
+ my @fk_schemas;
+ my $lastmatch = '';
+ foreach my $fk_schema ( sort keys %{$struct} ) {
+ foreach
+ my $fk_table ( sort keys %{ $struct->{$fk_schema}{'TABLE'} } )
+ {
+ foreach my $fk_column (
+ sort keys
+ %{ $struct->{$fk_schema}{'TABLE'}{$fk_table}{'COLUMN'} }
+ )
+ {
+ foreach my $fk_con (
+ sort keys %{
+ $struct->{$fk_schema}{'TABLE'}{$fk_table}
+ {'COLUMN'}{$fk_column}{'CON'}
+ }
+ )
+ {
+ if ( $struct->{$fk_schema}{'TABLE'}{$fk_table}
+ {'COLUMN'}{$fk_column}{'CON'}{$fk_con}{'TYPE'}
+ eq 'FOREIGN KEY'
+ and $struct->{$fk_schema}{'TABLE'}{$fk_table}
+ {'COLUMN'}{$fk_column}{'CON'}{$fk_con}
+ {'FKTABLE'} eq $table
+ and $struct->{$fk_schema}{'TABLE'}{$fk_table}
+ {'COLUMN'}{$fk_column}{'CON'}{$fk_con}
+ {'FKSCHEMA'} eq $schema
+ and $lastmatch ne "$fk_schema$fk_table" )
+ {
+ my $fksgmlid = sgml_safe_id(
+ join( '.',
+ $fk_schema,
+ $struct->{$fk_schema}{'TABLE'}
+ {$fk_table}{'TYPE'},
+ $fk_table )
+ );
+ push @fk_schemas,
+ {
+ fk_column_number =>
+ $struct->{$fk_schema}{'TABLE'}{$fk_table}
+ {'COLUMN'}{$fk_column}{'ORDER'},
+ fk_sgmlid => $fksgmlid,
+ fk_schema => $fk_schema,
+ fk_schema_dbk => docbook($fk_schema),
+ fk_schema_dot => graphviz($fk_schema),
+ fk_table => $fk_table,
+ fk_table_dbk => docbook($fk_table),
+ fk_table_dot => graphviz($fk_table),
+ };
+
+ # only have the count if there is more than 1 schema
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $fk_schemas[-1]{"number_of_schemas"} =
+ scalar( keys %{$struct} );
+ }
+
+ $lastmatch = "$fk_schema$fk_table";
+ }
+ }
+ }
+ }
+ }
+
+ # List off permissions
+ my @permissions;
+ foreach my $user (
+ sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'} } )
+ {
+ push @permissions,
+ {
+ schema => $schema,
+ schema_dbk => docbook($schema),
+ schema_dot => graphviz($schema),
+ table => $table,
+ table_dbk => docbook($table),
+ table_dot => graphviz($table),
+ user => $user,
+ user_dbk => docbook($user),
+ };
+
+ # only have the count if there is more than 1 schema
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $permissions[-1]{"number_of_schemas"} =
+ scalar( keys %{$struct} );
+ }
+
+ foreach my $perm (
+ keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user} }
+ )
+ {
+ if ( $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user}
+ {$perm} == 1 )
+ {
+ $permissions[-1]{ lower($perm) } = 1;
+ }
+ }
+
+ }
+
+ # Increment and record the object ID
+ $tableids{"$schema$table"} = ++$object_id;
+ my $viewdef = sql_prettyprint(
+ $struct->{$schema}{'TABLE'}{$table}{'VIEW_DEF'} );
+
+ # Truncate comment for Dia
+ my $comment_dia =
+ $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'};
+ $comment_dia =~ s/^(.{35}).{5,}(.{5})$/$1 ... $2/g
+ if ( defined($comment_dia) );
+
+ push @tables, {
+ object_id => $object_id,
+ object_id_dbk => docbook($object_id),
+
+ schema => $schema,
+ schema_dbk => docbook($schema),
+ schema_dot => graphviz($schema),
+ schema_sgmlid => sgml_safe_id( $schema . ".schema" ),
+
+ # Statistics
+ stats_enabled => $statistics,
+ stats_dead_bytes => useUnits(
+ $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'}
+ ),
+ stats_dead_bytes_dbk => docbook(
+ useUnits(
+ $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'}
+ )
+ ),
+ stats_free_bytes =>
+ useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} ),
+ stats_free_bytes_dbk => docbook(
+ useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} )
+ ),
+ stats_table_bytes =>
+ useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} ),
+ stats_table_bytes_dbk => docbook(
+ useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} )
+ ),
+ stats_tuple_count =>
+ $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'},
+ stats_tuple_count_dbk =>
+ docbook( $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'} ),
+ stats_tuple_bytes =>
+ useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} ),
+ stats_tuple_bytes_dbk => docbook(
+ useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} )
+ ),
+
+ table => $table,
+ table_dbk => docbook($table),
+ table_dot => graphviz($table),
+ table_sgmlid => sgml_safe_id(
+ join( '.',
+ $schema, $struct->{$schema}{'TABLE'}{$table}{'TYPE'},
+ $table )
+ ),
+ table_comment =>
+ $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'},
+ table_comment_dbk =>
+ docbook( $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'} ),
+ table_comment_dia => $comment_dia,
+ view_definition => $viewdef,
+ view_definition_dbk => docbook($viewdef),
+ columns => \@columns,
+ constraints => \@constraints,
+ fk_schemas => \@fk_schemas,
+ indexes => \@indexes,
+ inherits => \@inherits,
+ permissions => \@permissions,
+ };
+
+ # only have the count if there is more than 1 schema
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $tables[-1]{"number_of_schemas"} = scalar( keys %{$struct} );
+ }
+ }
+
+ # Dump out list of functions
+ my @functions;
+ foreach my $function ( sort keys %{ $struct->{$schema}{'FUNCTION'} } ) {
+ push @functions,
+ {
+ function => $function,
+ function_dbk => docbook($function),
+ function_sgmlid =>
+ sgml_safe_id( join( '.', $schema, 'function', $function ) ),
+ function_comment =>
+ $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'},
+ function_comment_dbk => docbook(
+ $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'}
+ ),
+ function_language =>
+ uc( $struct->{$schema}{'FUNCTION'}{$function}{'LANGUAGE'} ),
+ function_returns =>
+ $struct->{$schema}{'FUNCTION'}{$function}{'RETURNS'},
+ function_source =>
+ $struct->{$schema}{'FUNCTION'}{$function}{'SOURCE'},
+ schema => $schema,
+ schema_dbk => docbook($schema),
+ schema_dot => graphviz($schema),
+ schema_sgmlid => sgml_safe_id( $schema . ".schema" ),
+ };
+
+ # only have the count if there is more than 1 schema
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $functions[-1]{"number_of_schemas"} = scalar( keys %{$struct} );
+ }
+ }
+
+ push @schemas,
+ {
+ schema => $schema,
+ schema_dbk => docbook($schema),
+ schema_dot => graphviz($schema),
+ schema_sgmlid => sgml_safe_id( $schema . ".schema" ),
+ schema_comment => $struct->{$schema}{'SCHEMA'}{'COMMENT'},
+ schema_comment_dbk =>
+ docbook( $struct->{$schema}{'SCHEMA'}{'COMMENT'} ),
+ functions => \@functions,
+ tables => \@tables,
+ };
+
+ # Build the array of schemas
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $schemas[-1]{"number_of_schemas"} = scalar( keys %{$struct} );
+ }
+ }
+
+ # Link the various components together via the template.
+ my @fk_links;
+ my @fkeys;
+ foreach my $schema ( sort keys %{$struct} ) {
+ foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) {
+ foreach my $column (
+ sort {
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a}
+ {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table}
+ {'COLUMN'}{$b}{'ORDER'}
+ }
+ keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} }
+ )
+ {
+ foreach my $con (
+ sort keys %{
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}
+ }
+ )
+ {
+
+ # To prevent a multi-column foreign key from appearing
+ # several times, we've opted
+ # to simply display the first column of any given key.
+ # Since column numbering always starts at 1
+ # for foreign keys.
+ if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY'
+ && $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+ {$column}{'CON'}{$con}{'COLNUM'} == 1 )
+ {
+
+ # Pull out some of the longer keys
+ my $ref_table =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'FKTABLE'};
+ my $ref_schema =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'FKSCHEMA'};
+ my $ref_column =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'FK-COL NAME'};
+
+ # Default values cause these elements to attach
+ # to the bottom in Dia
+ # If a KEYGROUP is not defined, it's a single column.
+ # Modify the ref_con and key_con variables to attach
+ # the to the columns connection point directly.
+ my $ref_con = 0;
+ my $key_con = 0;
+ my $keycon_offset = 0;
+ if (
+ !defined(
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+ {$column}{'CON'}{$con}{'KEYGROUP'}
+ )
+ )
+ {
+ $ref_con =
+ $struct->{$ref_schema}{'TABLE'}{$ref_table}
+ {'COLUMN'}{$ref_column}{'ORDER'} || 0;
+ $key_con =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+ {$column}{'ORDER'} || 0;
+ $keycon_offset = 1;
+ }
+
+ # Bump object_id
+ $object_id++;
+
+ push @fk_links,
+ {
+ fk_link_name => $con,
+ fk_link_name_dbk => docbook($con),
+ fk_link_name_dot => graphviz($con),
+ handle0_connection => $key_con,
+ handle0_connection_dbk => docbook($key_con),
+ handle0_connection_dia => 6 + ( $key_con * 2 ),
+ handle0_name => $table,
+ handle0_name_dbk => docbook($table),
+ handle0_schema => $schema,
+ handle0_to => $tableids{"$schema$table"},
+ handle0_to_dbk =>
+ docbook( $tableids{"$schema$table"} ),
+ handle1_connection => $ref_con,
+ handle1_connection_dbk => docbook($ref_con),
+ handle1_connection_dia => 6 +
+ ( $ref_con * 2 ) +
+ $keycon_offset,
+ handle1_name => $ref_table,
+ handle1_name_dbk => docbook($ref_table),
+ handle1_schema => $ref_schema,
+ handle1_to => $tableids{"$ref_schema$ref_table"},
+ handle1_to_dbk =>
+ docbook( $tableids{"$ref_schema$ref_table"} ),
+ object_id => $object_id,
+ object_id_dbk => docbook($object_id),
+ };
+
+ # Build the array of schemas
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $fk_links[-1]{"number_of_schemas"} =
+ scalar( keys %{$struct} );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ # Make database level comment information
+ my @timestamp = localtime();
+ my $dumped_on = sprintf( "%04d-%02d-%02d",
+ $timestamp[5] + 1900,
+ $timestamp[4] + 1,
+ $timestamp[3] );
+ my $database_comment = $db->{$database}{'COMMENT'};
+
+ # Loop through each template found in the supplied path.
+ # Output the results of the template as <filename>.<extension>
+ # into the current working directory.
+ my @template_files = glob( $template_path . '/*.tmpl' );
+
+ # Ensure we've told the user if we don't find any files.
+ triggerError("Templates files not found in $template_path")
+ if ( $#template_files < 0 );
+
+ # Process all found templates.
+ foreach my $template_file (@template_files) {
+ ( my $file_extension = $template_file ) =~
+ s/^(?:.*\/|)([^\/]+)\.tmpl$/$1/;
+ next
+ if ( defined($wanted_output) && $file_extension ne $wanted_output );
+ my $output_filename = "$output_filename_base.$file_extension";
+ print "Producing $output_filename from $template_file\n";
+
+ my $template = HTML::Template->new(
+ filename => $template_file,
+ die_on_bad_params => 0,
+ global_vars => 0,
+ strict => 1,
+ loop_context_vars => 1
+ );
+
+ $template->param(
+ database => $database,
+ database_dbk => docbook($database),
+ database_sgmlid => sgml_safe_id($database),
+ database_comment => $database_comment,
+ database_comment_dbk => docbook($database_comment),
+ dumped_on => $dumped_on,
+ dumped_on_dbk => docbook($dumped_on),
+ fk_links => \@fk_links,
+ schemas => \@schemas,
+ );
+
+ sysopen( FH, $output_filename, O_WRONLY | O_TRUNC | O_CREAT, 0644 )
+ or die "Can't open $output_filename: $!";
+ print FH $template->output();
+ }
+} ## end sub write_using_templates($$$$$)
+
+######
+# sgml_safe_id
+# Safe SGML ID Character replacement
+sub sgml_safe_id($) {
+ my $string = shift;
+
+ # Lets use the keyword ARRAY in place of the square brackets
+ # to prevent duplicating a non-array equivelent
+ $string =~ s/\[\]/ARRAY-/g;
+
+ # Brackets, spaces, commads, underscores are not valid 'id' characters
+ # replace with as few -'s as possible.
+ $string =~ s/[ "',)(_-]+/-/g;
+
+ # Don't want a - at the end either. It looks silly.
+ $string =~ s/-$//g;
+
+ return ($string);
+}
+
+#####
+# lower
+# LowerCase the string
+sub lower($) {
+ my $string = shift;
+
+ $string =~ tr/A-Z/a-z/;
+
+ return ($string);
+}
+
+#####
+# useUnits
+# Tack on base 2 metric units
+sub useUnits($) {
+ my ($value) = @_;
+
+ return '' if ( !defined($value) );
+
+ my @units = ( 'Bytes', 'KiBytes', 'MiBytes', 'GiBytes', 'TiBytes' );
+ my $loop = 0;
+
+ while ( $value >= 1024 ) {
+ $loop++;
+
+ $value = $value / 1024;
+ }
+
+ return ( sprintf( "%.2f %s", $value, $units[$loop] ) );
+}
+
+#####
+# docbook
+# Docbook output is special in that we may or may not want to escape
+# the characters inside the string depending on a string prefix.
+sub docbook($) {
+ my $string = shift;
+
+ if ( defined($string) ) {
+ if ( $string =~ /^\@DOCBOOK/ ) {
+ $string =~ s/^\@DOCBOOK//;
+ }
+ else {
+ $string =~ s/&(?!(amp|lt|gr|apos|quot);)/&amp;/g;
+ $string =~ s/</&lt;/g;
+ $string =~ s/>/&gt;/g;
+ $string =~ s/'/&apos;/g;
+ $string =~ s/"/&quot;/g;
+ }
+ }
+ else {
+
+ # Return an empty string when all else fails
+ $string = '';
+ }
+
+ return ($string);
+}
+
+#####
+# graphviz
+# GraphViz output requires that special characters (like " and whitespace) must be preceeded
+# by a \ when a part of a lable.
+sub graphviz($) {
+ my $string = shift;
+
+ # Ensure we don't return an least a empty string
+ $string = '' if ( !defined($string) );
+
+ $string =~ s/([\s"'])/\\$1/g;
+
+ return ($string);
+}
+
+#####
+# sql_prettyprint
+# Clean up SQL into something presentable
+sub sql_prettyprint($) {
+ my $string = shift;
+
+ # If nothing has been sent in, return an empty string
+ if ( !defined($string) ) {
+ return '';
+ }
+
+ # Initialize Result string
+ my $result = '';
+
+ # List of tokens to split on
+ my $tok =
+ "SELECT|FROM|WHERE|HAVING|GROUP BY|ORDER BY|OR|AND|LEFT JOIN|RIGHT JOIN"
+ . "|LEFT OUTER JOIN|LEFT INNER JOIN|INNER JOIN|RIGHT OUTER JOIN|RIGHT INNER JOIN"
+ . "|JOIN|UNION ALL|UNION|EXCEPT|USING|ON|CAST|[\(\),]";
+
+ my $key = 0;
+ my $bracket = 0;
+ my $depth = 0;
+ my $indent = 6;
+
+ # XXX: Split is wrong -- match would do
+ foreach my $elem ( split( /(\"[^\"]*\"|'[^']*'|$tok)/, $string ) ) {
+ my $format;
+
+ # Skip junk tokens
+ if ( $elem =~ /^[\s]?$/ ) {
+ next;
+ }
+
+ # NOTE: Should we drop leading spaces?
+ # $elem =~ s/^\s//;
+
+ # Close brackets are special
+ # Bring depth in a level
+ if ( $elem =~ /\)/ ) {
+ $depth = $depth - $indent;
+ if ( $key == 1 or $bracket == 1 ) {
+ $format = "%s%s";
+ }
+ else {
+ $format = "%s\n%" . $depth . "s";
+ }
+
+ $key = 0;
+ $bracket = 0;
+ }
+
+ # Open brackets are special
+ # Bump depth out a level
+ elsif ( $elem =~ /\(/ ) {
+ if ( $key == 1 ) {
+ $format = "%s %s";
+ }
+ else {
+ $format = "%s\n%" . $depth . "s";
+ }
+ $depth = $depth + $indent;
+ $bracket = 1;
+ $key = 0;
+ }
+
+ # Key element
+ # Token from our list -- format on left hand side of the equation
+ # when appropriate.
+ elsif ( $elem =~ /$tok/ ) {
+ if ( $key == 1 ) {
+ $format = "%s%s";
+ }
+ else {
+ $format = "%s\n%" . $depth . "s";
+ }
+
+ $key = 1;
+ $bracket = 0;
+ }
+
+ # Value
+ # Format for right hand side of the equation
+ else {
+ $format = "%s%s";
+
+ $key = 0;
+ }
+
+ # Add the new format string to the result
+ $result = sprintf( $format, $result, $elem );
+ }
+
+ return $result;
+} ## end sub sql_prettyprint($)
+
+##
+# triggerError
+# Print out a supplied error message and exit the script.
+sub triggerError($) {
+ my ($error) = @_;
+
+ # Test error
+ if ( !defined($error) || $error eq '' ) {
+
+ # Suppress prototype checking in call to self
+ &triggerError("triggerError: Unknown error");
+ }
+ printf( "\n\n%s\n", $error );
+
+ exit 2;
+}
+
+#####
+# usage
+sub usage($$$) {
+ my ( $basename, $database, $dbuser ) = @_;
+ print <<USAGE
+Usage:
+ $basename [options] [dbname [username]]
+
+Options:
+ -d <dbname> Specify database name to connect to (default: $database)
+ -f <file> Specify output file prefix (default: $database)
+ -h <host> Specify database server host (default: localhost)
+ -p <port> Specify database server port (default: 5432)
+ -u <username> Specify database username (default: $dbuser)
+ --password=<pw> Specify database password (default: blank)
+ --password Have $basename prompt for a password
+
+ -l <path> Path to the templates (default: /usr/local/share/postgresql_autodoc)
+ -t <output> Type of output wanted (default: All in template library)
+
+ -s <schema> Specify a specific schema to match. Technically this is a regular
+ expression but anything other than a specific name may have unusual
+ results.
+ --table=<args> Tables to export. Multiple tables may be provided using a
+ comma-separated list.
+
+ --statistics In 7.4 and later, with the contrib module pgstattuple installed we
+ can gather statistics on the tables in the database
+ (average size, free space, disk space used, dead tuple counts, etc.)
+ This is disk intensive on large databases as all pages must be visited.
+USAGE
+ ;
+ exit 1;
+}
+
+sub single_quote {
+ my $attr = $_;
+ $attr =~ s/^\s+|\s+$//g;
+ return qq{'$attr'};
+}
+
+##
+# Kick off execution of main()
+main($ARGV);
+
diff --git a/postgresql_autodoc/postgresql_autodoc.pl b/postgresql_autodoc/postgresql_autodoc.pl
new file mode 100755
index 0000000..fa8ac96
--- /dev/null
+++ b/postgresql_autodoc/postgresql_autodoc.pl
@@ -0,0 +1,1907 @@
+#!/usr/bin/env perl
+# -- # -*- Perl -*-w
+# $Header: /cvsroot/autodoc/autodoc/postgresql_autodoc.pl,v 1.21 2008/03/12 19:00:56 rbt Exp $
+# Imported 1.22 2002/02/08 17:09:48 into sourceforge
+
+# Postgres Auto-Doc Version 1.31
+
+# License
+# -------
+# Copyright (c) 2001-2007, Rod Taylor
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+#
+# 3. Neither the name of the InQuent Technologies Inc. nor the names
+# of its contributors may be used to endorse or promote products
+# derived from this software without specific prior written
+# permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD
+# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# About Project
+# -------------
+# Various details about the project and related items can be found at
+# the website
+#
+# http://www.rbt.ca/autodoc/
+
+use strict;
+use warnings;
+
+use DBI;
+use Fcntl;
+
+# Allows file templates
+use HTML::Template;
+
+# Allow reading a password from stdin
+use Term::ReadKey;
+
+sub main($) {
+ my ($ARGV) = @_;
+
+ my %db;
+
+ # The templates path
+ # @@TEMPLATE-DIR@@ will be replaced by make in the build phase
+ my $template_path = '@@TEMPLATE-DIR@@';
+
+ # Setup the default connection variables based on the environment
+ my $dbuser = $ENV{'PGUSER'};
+ $dbuser ||= $ENV{'USER'};
+
+ my $database = $ENV{'PGDATABASE'};
+ $database ||= $dbuser;
+
+ my $dbhost = $ENV{'PGHOST'};
+ $dbhost ||= "";
+
+ my $dbport = $ENV{'PGPORT'};
+ $dbport ||= "";
+
+ # Determine whether we need a password to connect
+ my $needpass = 0;
+
+ my $dbpass = "";
+ my $output_filename_base = $database;
+
+ # Tracking variables
+ my $dbisset = 0;
+ my $fileisset = 0;
+
+ my $only_schema;
+
+ my $table_out;
+
+ my $wanted_output = undef; # means all types
+
+ my $statistics = 0;
+
+ # Fetch base and dirnames. Useful for Usage()
+ my $basename = $0;
+ my $dirname = $0;
+ $basename =~ s|^.*/([^/]+)$|$1|;
+ $dirname =~ s|^(.*)/[^/]+$|$1|;
+
+ # If template_path isn't defined, lets set it ourselves
+ $template_path = $dirname if ( !defined($template_path) );
+
+ for ( my $i = 0 ; $i <= $#ARGV ; $i++ ) {
+ ARGPARSE: for ( $ARGV[$i] ) {
+
+ # Set the database
+ /^-d$/ && do {
+ $database = $ARGV[ ++$i ];
+ $dbisset = 1;
+ if ( !$fileisset ) {
+ $output_filename_base = $database;
+ }
+ last;
+ };
+
+ # Set the user
+ /^-[uU]$/ && do {
+ $dbuser = $ARGV[ ++$i ];
+ if ( !$dbisset ) {
+ $database = $dbuser;
+ if ( !$fileisset ) {
+ $output_filename_base = $database;
+ }
+ }
+ last;
+ };
+
+ # Set the hostname
+ /^-h$/ && do { $dbhost = $ARGV[ ++$i ]; last; };
+
+ # Set the Port
+ /^-p$/ && do { $dbport = $ARGV[ ++$i ]; last; };
+
+ # Set the users password
+ /^--password=/ && do {
+ $dbpass = $ARGV[$i];
+ $dbpass =~ s/^--password=//g;
+ last;
+ };
+
+ # Make sure we get a password before attempting to conenct
+ /^--password$/ && do {
+ $needpass = 1;
+ last;
+ };
+
+ # Set the base of the filename. The extensions pulled
+ # from the templates will be appended to this name
+ /^-f$/ && do {
+ $output_filename_base = $ARGV[ ++$i ];
+ $fileisset = 1;
+ last;
+ };
+
+ # Set the template directory explicitly
+ /^(-l|--library)$/ && do {
+ $template_path = $ARGV[ ++$i ];
+ last;
+ };
+
+ # Set the output type
+ /^(-t|--type)$/ && do {
+ $wanted_output = $ARGV[ ++$i ];
+ last;
+ };
+
+ # User has requested a single schema dump and provided a pattern
+ /^(-s|--schema)$/ && do {
+ $only_schema = $ARGV[ ++$i ];
+ last;
+ };
+
+ # One might dump a table's set (comma-separated) or just one
+ # If dumping a set of specific tables do NOT dump out the functions
+ # in this database. Generates noise in the output
+ # that most likely isn't wanted. Check for $table_out around the
+ # function gathering location.
+ /^--table=/ && do {
+ my $some_table = $ARGV[$i];
+ $some_table =~ s/^--table=//g;
+
+ my @tables_in = split( ',', $some_table );
+ sub single_quote;
+ $table_out = join( ',', map( single_quote, @tables_in ) );
+
+ last;
+ };
+
+ # Check to see if Statistics have been requested
+ /^--statistics$/ && do {
+ $statistics = 1;
+ last;
+ };
+
+ # Help is wanted, redirect user to usage()
+ /^-\?$/ && do { usage( $basename, $database, $dbuser ); last; };
+ /^--help$/ && do { usage( $basename, $database, $dbuser ); last; };
+ }
+ }
+
+ # If no arguments have been provided, connect to the database anyway but
+ # inform the user of what we're doing.
+ if ( $#ARGV <= 0 ) {
+ print <<Msg
+No arguments set. Use '$basename --help' for help
+
+Connecting to database '$database' as user '$dbuser'
+Msg
+ ;
+ }
+
+ # If needpass has been set but no password was provided, prompt the user
+ # for a password.
+ if ( $needpass and not $dbpass ) {
+ print "Password: ";
+ ReadMode 'noecho';
+ $dbpass = ReadLine 0;
+ chomp $dbpass;
+ ReadMode 'normal';
+ print "\n";
+ }
+
+ # Database Connection
+ my $dsn = "dbi:Pg:dbname=$database";
+ $dsn .= ";host=$dbhost" if ( "$dbhost" ne "" );
+ $dsn .= ";port=$dbport" if ( "$dbport" ne "" );
+
+ info_collect( [ $dsn, $dbuser, $dbpass ],
+ \%db, $database, $only_schema, $statistics, $table_out );
+
+ # Write out *ALL* templates
+ write_using_templates( \%db, $database, $statistics, $template_path,
+ $output_filename_base, $wanted_output );
+} ## end sub main($)
+
+##
+# info_collect
+#
+# Pull out all of the applicable information about a specific database
+sub info_collect {
+ my ( $dbConnect, $db, $database, $only_schema, $statistics, $table_out ) =
+ @_;
+
+ my $dbh = DBI->connect( @{$dbConnect} )
+ or triggerError("Unable to connect due to: $DBI::errstr");
+
+ $dbh->do("set client_encoding to 'UTF-8'")
+ or triggerError("could not set client_encoding to UTF-8: $DBI::errstr");
+
+ my %struct;
+ $db->{$database}{'STRUCT'} = \%struct;
+ my $struct = $db->{$database}{'STRUCT'};
+
+ # PostgreSQL's version is used to determine what queries are required
+ # to retrieve a given information set.
+ if ( $dbh->{pg_server_version} < 70300 ) {
+ die("PostgreSQL 7.3 and later are supported");
+ }
+
+ # Ensure we only retrieve information for the requested schemas.
+ #
+ # system_schema -> The primary system schema for a database.
+ # Public is used for verions prior to 7.3
+ #
+ # system_schema_list -> The list of schemas which we are not supposed
+ # to gather information for.
+ # TODO: Merge with system_schema in array form.
+ #
+ # schemapattern -> The schema the user provided as a command
+ # line option.
+ my $schemapattern = '^';
+ my $system_schema = 'pg_catalog';
+ my $system_schema_list =
+ 'pg_catalog|pg_toast|pg_temp_[0-9]+|information_schema';
+ if ( defined($only_schema) ) {
+ $schemapattern = '^' . $only_schema . '$';
+ }
+
+ #
+ # List of queries which are used to gather information from the
+ # database. The queries differ based on version but should
+ # provide similar output. At some point it should be safe to remove
+ # support for older database versions.
+ #
+
+ # Fetch the description of the database
+ my $sql_Database = q{
+ SELECT pg_catalog.obj_description(oid, 'pg_database') as comment
+ FROM pg_catalog.pg_database
+ WHERE datname = '$database';
+ };
+
+ # Pull out a list of tables, views and special structures.
+ my $sql_Tables = qq{
+ SELECT nspname as namespace
+ , relname as tablename
+ , pg_catalog.pg_get_userbyid(relowner) AS tableowner
+ , relhasindex as hasindexes
+ , relhasrules as hasrules
+ , reltriggers as hastriggers
+ , pg_class.oid
+ , pg_catalog.obj_description(pg_class.oid, 'pg_class') as table_description
+ , relacl
+ , CASE
+ WHEN relkind = 'r' THEN
+ 'table'
+ WHEN relkind = 's' THEN
+ 'special'
+ ELSE
+ 'view'
+ END as reltype
+ , CASE
+ WHEN relkind = 'v' THEN
+ pg_get_viewdef(pg_class.oid)
+ ELSE
+ NULL
+ END as view_definition
+ FROM pg_catalog.pg_class
+ JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid)
+ WHERE relkind IN ('r', 's', 'v')
+ AND nspname !~ '$system_schema_list'
+ AND nspname ~ '$schemapattern'
+ };
+ $sql_Tables .= qq{ AND relname IN ($table_out)} if defined($table_out);
+
+ # - uses pg_class.oid
+ my $sql_Columns = q{
+ SELECT attname as column_name
+ , attlen as column_length
+ , CASE
+ WHEN pg_type.typname = 'int4'
+ AND EXISTS (SELECT TRUE
+ FROM pg_catalog.pg_depend
+ JOIN pg_catalog.pg_class ON (pg_class.oid = objid)
+ WHERE refobjsubid = attnum
+ AND refobjid = attrelid
+ AND relkind = 'S') THEN
+ 'serial'
+ WHEN pg_type.typname = 'int8'
+ AND EXISTS (SELECT TRUE
+ FROM pg_catalog.pg_depend
+ JOIN pg_catalog.pg_class ON (pg_class.oid = objid)
+ WHERE refobjsubid = attnum
+ AND refobjid = attrelid
+ AND relkind = 'S') THEN
+ 'bigserial'
+ ELSE
+ pg_catalog.format_type(atttypid, atttypmod)
+ END as column_type
+ , CASE
+ WHEN attnotnull THEN
+ cast('NOT NULL' as text)
+ ELSE
+ cast('' as text)
+ END as column_null
+ , CASE
+ WHEN pg_type.typname IN ('int4', 'int8')
+ AND EXISTS (SELECT TRUE
+ FROM pg_catalog.pg_depend
+ JOIN pg_catalog.pg_class ON (pg_class.oid = objid)
+ WHERE refobjsubid = attnum
+ AND refobjid = attrelid
+ AND relkind = 'S') THEN
+ NULL
+ ELSE
+ adsrc
+ END as column_default
+ , pg_catalog.col_description(attrelid, attnum) as column_description
+ , attnum
+ FROM pg_catalog.pg_attribute
+ JOIN pg_catalog.pg_type ON (pg_type.oid = atttypid)
+ LEFT JOIN pg_catalog.pg_attrdef ON ( attrelid = adrelid
+ AND attnum = adnum)
+ WHERE attnum > 0
+ AND attisdropped IS FALSE
+ AND attrelid = ?;
+ };
+
+ my $sql_Table_Statistics;
+ if ( $statistics == 1 ) {
+ if ( $dbh->{pg_server_version} <= 70300 ) {
+ triggerError(
+ "Table statistics supported on PostgreSQL 7.4 and later.\n"
+ . "Remove --statistics flag and try again." );
+ }
+
+ $sql_Table_Statistics = q{
+ SELECT table_len
+ , tuple_count
+ , tuple_len
+ , CAST(tuple_percent AS numeric(20,2)) AS tuple_percent
+ , dead_tuple_count
+ , dead_tuple_len
+ , CAST(dead_tuple_percent AS numeric(20,2)) AS dead_tuple_percent
+ , CAST(free_space AS numeric(20,2)) AS free_space
+ , CAST(free_percent AS numeric(20,2)) AS free_percent
+ FROM pgstattuple(CAST(? AS oid));
+ };
+ }
+
+ my $sql_Indexes = q{
+ SELECT schemaname
+ , tablename
+ , indexname
+ , substring( indexdef
+ FROM position('(' IN indexdef) + 1
+ FOR length(indexdef) - position('(' IN indexdef) - 1
+ ) AS indexdef
+ FROM pg_catalog.pg_indexes
+ WHERE substring(indexdef FROM 8 FOR 6) != 'UNIQUE'
+ AND schemaname = ?
+ AND tablename = ?;
+ };
+
+ my $sql_Inheritance = qq{
+ SELECT parnsp.nspname AS par_schemaname
+ , parcla.relname AS par_tablename
+ , chlnsp.nspname AS chl_schemaname
+ , chlcla.relname AS chl_tablename
+ FROM pg_catalog.pg_inherits
+ JOIN pg_catalog.pg_class AS chlcla ON (chlcla.oid = inhrelid)
+ JOIN pg_catalog.pg_namespace AS chlnsp ON (chlnsp.oid = chlcla.relnamespace)
+ JOIN pg_catalog.pg_class AS parcla ON (parcla.oid = inhparent)
+ JOIN pg_catalog.pg_namespace AS parnsp ON (parnsp.oid = parcla.relnamespace)
+ WHERE chlnsp.nspname = ?
+ AND chlcla.relname = ?
+ AND chlnsp.nspname ~ '$schemapattern'
+ AND parnsp.nspname ~ '$schemapattern';
+ };
+
+ # Fetch the list of PRIMARY and UNIQUE keys
+ my $sql_Primary_Keys = q{
+ SELECT conname AS constraint_name
+ , pg_catalog.pg_get_indexdef(d.objid) AS constraint_definition
+ , CASE
+ WHEN contype = 'p' THEN
+ 'PRIMARY KEY'
+ ELSE
+ 'UNIQUE'
+ END as constraint_type
+ FROM pg_catalog.pg_constraint AS c
+ JOIN pg_catalog.pg_depend AS d ON (d.refobjid = c.oid)
+ WHERE contype IN ('p', 'u')
+ AND deptype = 'i'
+ AND conrelid = ?;
+ };
+
+ # FOREIGN KEY fetch
+ #
+ # Don't return the constraint name if it was automatically generated by
+ # PostgreSQL. The $N (where N is an integer) is not a descriptive enough
+ # piece of information to be worth while including in the various outputs.
+ my $sql_Foreign_Keys = qq{
+ SELECT pg_constraint.oid
+ , pg_namespace.nspname AS namespace
+ , CASE WHEN substring(pg_constraint.conname FROM 1 FOR 1) = '\$' THEN ''
+ ELSE pg_constraint.conname
+ END AS constraint_name
+ , conkey AS constraint_key
+ , confkey AS constraint_fkey
+ , confrelid AS foreignrelid
+ FROM pg_catalog.pg_constraint
+ JOIN pg_catalog.pg_class ON (pg_class.oid = conrelid)
+ JOIN pg_catalog.pg_class AS pc ON (pc.oid = confrelid)
+ JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid)
+ JOIN pg_catalog.pg_namespace AS pn ON (pn.oid = pc.relnamespace)
+ WHERE contype = 'f'
+ AND conrelid = ?
+ AND pg_namespace.nspname ~ '$schemapattern'
+ AND pn.nspname ~ '$schemapattern';
+ };
+
+ my $sql_Foreign_Key_Arg = q{
+ SELECT attname AS attribute_name
+ , relname AS relation_name
+ , nspname AS namespace
+ FROM pg_catalog.pg_attribute
+ JOIN pg_catalog.pg_class ON (pg_class.oid = attrelid)
+ JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid)
+ WHERE attrelid = ?
+ AND attnum = ?;
+ };
+
+ # Fetch CHECK constraints
+ my $sql_Constraint;
+ if ( $dbh->{pg_server_version} >= 70400 ) {
+ $sql_Constraint = q{
+ SELECT pg_get_constraintdef(oid) AS constraint_source
+ , conname AS constraint_name
+ FROM pg_constraint
+ WHERE conrelid = ?
+ AND contype = 'c';
+ };
+ }
+ else {
+ $sql_Constraint = q{
+ SELECT 'CHECK ' || pg_catalog.substr(consrc, 2, length(consrc) - 2) AS constraint_source
+ , conname AS constraint_name
+ FROM pg_constraint
+ WHERE conrelid = ?
+ AND contype = 'c';
+ };
+ }
+
+ # Query for function information
+ my $sql_Function;
+ my $sql_FunctionArg;
+ if ( $dbh->{pg_server_version} >= 80000 ) {
+ $sql_Function = qq{
+ SELECT proname AS function_name
+ , nspname AS namespace
+ , lanname AS language_name
+ , pg_catalog.obj_description(pg_proc.oid, 'pg_proc') AS comment
+ , proargtypes AS function_args
+ , proargnames AS function_arg_names
+ , prosrc AS source_code
+ , proretset AS returns_set
+ , prorettype AS return_type
+ FROM pg_catalog.pg_proc
+ JOIN pg_catalog.pg_language ON (pg_language.oid = prolang)
+ JOIN pg_catalog.pg_namespace ON (pronamespace = pg_namespace.oid)
+ JOIN pg_catalog.pg_type ON (prorettype = pg_type.oid)
+ WHERE pg_namespace.nspname !~ '$system_schema_list'
+ AND pg_namespace.nspname ~ '$schemapattern'
+ AND proname != 'plpgsql_call_handler';
+ };
+
+ $sql_FunctionArg = q{
+ SELECT nspname AS namespace
+ , replace(pg_catalog.format_type(pg_type.oid, typtypmod)
+ , nspname ||'.'
+ , '') AS type_name
+ FROM pg_catalog.pg_type
+ JOIN pg_catalog.pg_namespace ON (pg_namespace.oid = typnamespace)
+ WHERE pg_type.oid = ?;
+ };
+ }
+ else {
+ $sql_Function = qq{
+ SELECT proname AS function_name
+ , nspname AS namespace
+ , lanname AS language_name
+ , pg_catalog.obj_description(pg_proc.oid, 'pg_proc') AS comment
+ , proargtypes AS function_args
+ , NULL AS function_arg_names
+ , prosrc AS source_code
+ , proretset AS returns_set
+ , prorettype AS return_type
+ FROM pg_catalog.pg_proc
+ JOIN pg_catalog.pg_language ON (pg_language.oid = prolang)
+ JOIN pg_catalog.pg_namespace ON (pronamespace = pg_namespace.oid)
+ JOIN pg_catalog.pg_type ON (prorettype = pg_type.oid)
+ WHERE pg_namespace.nspname !~ '$system_schema_list'
+ AND pg_namespace.nspname ~ '$schemapattern'
+ AND proname != 'plpgsql_call_handler';
+ };
+
+ $sql_FunctionArg = q{
+ SELECT nspname AS namespace
+ , replace(pg_catalog.format_type(pg_type.oid, typtypmod)
+ , nspname ||'.'
+ , '') AS type_name
+ FROM pg_catalog.pg_type
+ JOIN pg_catalog.pg_namespace ON (pg_namespace.oid = typnamespace)
+ WHERE pg_type.oid = ?;
+ };
+ }
+
+ # Fetch schema information.
+ my $sql_Schema = qq{
+ SELECT pg_catalog.obj_description(oid, 'pg_namespace') AS comment
+ , nspname as namespace
+ FROM pg_catalog.pg_namespace
+ WHERE pg_namespace.nspname !~ '$system_schema_list'
+ AND pg_namespace.nspname ~ '$schemapattern';
+ };
+
+ my $sth_Columns = $dbh->prepare($sql_Columns);
+ my $sth_Constraint = $dbh->prepare($sql_Constraint);
+ my $sth_Database = $dbh->prepare($sql_Database);
+ my $sth_Foreign_Keys = $dbh->prepare($sql_Foreign_Keys);
+ my $sth_Foreign_Key_Arg = $dbh->prepare($sql_Foreign_Key_Arg);
+ my $sth_Function = $dbh->prepare($sql_Function);
+ my $sth_FunctionArg = $dbh->prepare($sql_FunctionArg);
+ my $sth_Indexes = $dbh->prepare($sql_Indexes);
+ my $sth_Inheritance = $dbh->prepare($sql_Inheritance);
+ my $sth_Primary_Keys = $dbh->prepare($sql_Primary_Keys);
+ my $sth_Schema = $dbh->prepare($sql_Schema);
+ my $sth_Tables = $dbh->prepare($sql_Tables);
+ my $sth_Table_Statistics = $dbh->prepare($sql_Table_Statistics)
+ if ( $statistics == 1 );
+
+ # Fetch Database info
+ $sth_Database->execute();
+ my $dbinfo = $sth_Database->fetchrow_hashref;
+ if ( defined($dbinfo) ) {
+ $db->{$database}{'COMMENT'} = $dbinfo->{'comment'};
+ }
+
+ # Fetch tables and all things bound to tables
+ $sth_Tables->execute();
+ while ( my $tables = $sth_Tables->fetchrow_hashref ) {
+ my $reloid = $tables->{'oid'};
+ my $relname = $tables->{'tablename'};
+
+ my $schema = $tables->{'namespace'};
+
+ EXPRESSIONFOUND:
+
+ # Store permissions
+ my $acl = $tables->{'relacl'};
+
+ # Empty acl groups cause serious issues.
+ $acl ||= '';
+
+ # Strip array forming 'junk'.
+ $acl =~ s/^{//g;
+ $acl =~ s/}$//g;
+ $acl =~ s/"//g;
+
+ # Foreach acl
+ foreach ( split( /\,/, $acl ) ) {
+ my ( $user, $raw_permissions ) = split( /=/, $_ );
+
+ if ( defined($raw_permissions) ) {
+ if ( $user eq '' ) {
+ $user = 'PUBLIC';
+ }
+
+ # The section after the / is the user who granted the permissions
+ my ( $permissions, $granting_user ) =
+ split( /\//, $raw_permissions );
+
+ # Break down permissions to individual flags
+ if ( $permissions =~ /a/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'INSERT'} = 1;
+ }
+
+ if ( $permissions =~ /r/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'SELECT'} = 1;
+ }
+
+ if ( $permissions =~ /w/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'UPDATE'} = 1;
+ }
+
+ if ( $permissions =~ /d/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'DELETE'} = 1;
+ }
+
+ if ( $permissions =~ /R/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'RULE'} = 1;
+ }
+
+ if ( $permissions =~ /x/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'REFERENCES'} = 1;
+ }
+
+ if ( $permissions =~ /t/ ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+ {'TRIGGER'} = 1;
+ }
+ }
+ }
+
+ # Primitive Stats, but only if requested
+ if ( $statistics == 1 and $tables->{'reltype'} eq 'table' ) {
+ $sth_Table_Statistics->execute($reloid);
+
+ my $stats = $sth_Table_Statistics->fetchrow_hashref;
+
+ $struct->{$schema}{'TABLE'}{$relname}{'TABLELEN'} =
+ $stats->{'table_len'};
+ $struct->{$schema}{'TABLE'}{$relname}{'TUPLECOUNT'} =
+ $stats->{'tuple_count'};
+ $struct->{$schema}{'TABLE'}{$relname}{'TUPLELEN'} =
+ $stats->{'tuple_len'};
+ $struct->{$schema}{'TABLE'}{$relname}{'DEADTUPLELEN'} =
+ $stats->{'dead_tuple_len'};
+ $struct->{$schema}{'TABLE'}{$relname}{'FREELEN'} =
+ $stats->{'free_space'};
+ }
+
+ # Store the relation type
+ $struct->{$schema}{'TABLE'}{$relname}{'TYPE'} = $tables->{'reltype'};
+
+ # Store table description
+ $struct->{$schema}{'TABLE'}{$relname}{'DESCRIPTION'} =
+ $tables->{'table_description'};
+
+ # Store the view definition
+ $struct->{$schema}{'TABLE'}{$relname}{'VIEW_DEF'} =
+ $tables->{'view_definition'};
+
+ # Store constraints
+ $sth_Constraint->execute($reloid);
+ while ( my $cols = $sth_Constraint->fetchrow_hashref ) {
+ my $constraint_name = $cols->{'constraint_name'};
+ $struct->{$schema}{'TABLE'}{$relname}{'CONSTRAINT'}
+ {$constraint_name} = $cols->{'constraint_source'};
+ }
+
+ $sth_Columns->execute($reloid);
+ my $i = 1;
+ while ( my $cols = $sth_Columns->fetchrow_hashref ) {
+ my $column_name = $cols->{'column_name'};
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'ORDER'} = $cols->{'attnum'};
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'PRIMARY KEY'} = 0;
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'FKTABLE'} = '';
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'TYPE'} = $cols->{'column_type'};
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'NULL'} = $cols->{'column_null'};
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'DESCRIPTION'} = $cols->{'column_description'};
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+ {'DEFAULT'} = $cols->{'column_default'};
+ }
+
+ # Pull out both PRIMARY and UNIQUE keys based on the supplied query
+ # and the relation OID.
+ #
+ # Since there may be multiple UNIQUE indexes on a table, we append a
+ # number to the end of the the UNIQUE keyword which shows that they
+ # are a part of a related definition. I.e UNIQUE_1 goes with UNIQUE_1
+ #
+ $sth_Primary_Keys->execute($reloid);
+ my $unqgroup = 0;
+ while ( my $pricols = $sth_Primary_Keys->fetchrow_hashref ) {
+ my $index_type = $pricols->{'constraint_type'};
+ my $con = $pricols->{'constraint_name'};
+ my $indexdef = $pricols->{'constraint_definition'};
+
+ # Fetch the column list
+ my $column_list = $indexdef;
+ $column_list =~ s/.*\(([^)]+)\).*/$1/g;
+
+ # Split our column list and deal with all PRIMARY KEY fields
+ my @collist = split( ',', $column_list );
+
+ # Store the column number in the indextype field. Anything > 0
+ # indicates the column has this type of constraint applied to it.
+ my $column;
+ my $currentcol = $#collist + 1;
+ my $numcols = $#collist + 1;
+
+ # Bump group number if there are two or more columns
+ if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) {
+ $unqgroup++;
+ }
+
+ # Record the data to the structure.
+ while ( $column = pop(@collist) ) {
+ $column =~ s/\s$//;
+ $column =~ s/^\s//;
+ $column =~ s/^"//;
+ $column =~ s/"$//;
+
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'TYPE'} = $index_type;
+
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'COLNUM'} = $currentcol--;
+
+ # Record group number only when a multi-column
+ # constraint is involved
+ if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}
+ {'CON'}{$con}{'KEYGROUP'} = $unqgroup;
+ }
+ }
+ }
+
+ # FOREIGN KEYS like UNIQUE indexes can appear several times in
+ # a table in multi-column format. We use the same trick to
+ # record a numeric association to the foreign key reference.
+ $sth_Foreign_Keys->execute($reloid);
+ my $fkgroup = 0;
+ while ( my $forcols = $sth_Foreign_Keys->fetchrow_hashref ) {
+ my $column_oid = $forcols->{'oid'};
+ my $con = $forcols->{'constraint_name'};
+
+ # Declare variables for dataload
+ my @keylist;
+ my @fkeylist;
+ my $fschema;
+ my $ftable;
+
+ my $fkey = $forcols->{'constraint_fkey'};
+ my $keys = $forcols->{'constraint_key'};
+ my $frelid = $forcols->{'foreignrelid'};
+
+ # Since decent array support was not added until 7.4, and
+ # we want to support 7.3 as well, we parse the text version
+ # of the array by hand rather than combining this and
+ # Foreign_Key_Arg query into a single query.
+
+ my @fkeyset;
+ if ( ref $fkey eq 'ARRAY' ) {
+ @fkeyset = @{$fkey};
+ }
+ else { # DEPRECATED: DBD::Pg 1.49 and earlier
+ $fkey =~ s/^{//g;
+ $fkey =~ s/}$//g;
+ $fkey =~ s/"//g;
+ @fkeyset = split( /,/, $fkey );
+ }
+
+ my @keyset;
+ if ( ref $keys eq 'ARRAY' ) {
+ @keyset = @{$keys};
+ }
+ else { # DEPRECATED: DBD::Pg 1.49 and earlier
+ $keys =~ s/^{//g;
+ $keys =~ s/}$//g;
+ $keys =~ s/"//g;
+ @keyset = split( /,/, $keys );
+ }
+
+ # Convert the list of column numbers into column names for the
+ # local side.
+ foreach my $k (@keyset) {
+ $sth_Foreign_Key_Arg->execute( $reloid, $k );
+
+ my $row = $sth_Foreign_Key_Arg->fetchrow_hashref;
+
+ push( @keylist, $row->{'attribute_name'} );
+ }
+
+ # Convert the list of columns numbers into column names
+ # for the referenced side. Grab the table and namespace
+ # while we're here.
+ foreach my $k (@fkeyset) {
+ $sth_Foreign_Key_Arg->execute( $frelid, $k );
+
+ my $row = $sth_Foreign_Key_Arg->fetchrow_hashref;
+
+ push( @fkeylist, $row->{'attribute_name'} );
+ $fschema = $row->{'namespace'};
+ $ftable = $row->{'relation_name'};
+ }
+
+ # Deal with common catalog issues.
+ die "FKEY $con Broken -- fix your PostgreSQL installation"
+ if $#keylist != $#fkeylist;
+
+ # Load up the array based on the information discovered
+ # using the information retrieval methods above.
+ my $numcols = $#keylist + 1;
+ my $currentcol = $#keylist + 1;
+
+ # Bump group number if there are two or more columns involved
+ if ( $numcols >= 2 ) {
+ $fkgroup++;
+ }
+
+ # Record the foreign key to structure
+ while ( my $column = pop(@keylist)
+ and my $fkey = pop(@fkeylist) )
+ {
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'TYPE'} = 'FOREIGN KEY';
+
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'COLNUM'} = $currentcol--;
+
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'FKTABLE'} = $ftable;
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'FKSCHEMA'} = $fschema;
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+ {$con}{'FK-COL NAME'} = $fkey;
+
+ # Record group number only when a multi-column
+ # constraint is involved
+ if ( $numcols >= 2 ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}
+ {'CON'}{$con}{'KEYGROUP'} = $fkgroup;
+ }
+ }
+ }
+
+ # Pull out index information
+ $sth_Indexes->execute( $schema, $relname );
+ while ( my $idx = $sth_Indexes->fetchrow_hashref ) {
+ $struct->{$schema}{'TABLE'}{$relname}{'INDEX'}
+ { $idx->{'indexname'} } = $idx->{'indexdef'};
+ }
+
+ # Extract Inheritance information
+ $sth_Inheritance->execute( $schema, $relname );
+ while ( my $inherit = $sth_Inheritance->fetchrow_hashref ) {
+ my $parSch = $inherit->{'par_schemaname'};
+ my $parTab = $inherit->{'par_tablename'};
+ $struct->{$schema}{'TABLE'}{$relname}{'INHERIT'}{$parSch}{$parTab} =
+ 1;
+ }
+ }
+
+ # Function Handling
+ $sth_Function->execute();
+ while ( my $functions = $sth_Function->fetchrow_hashref and not $table_out )
+ {
+ my $functionname = $functions->{'function_name'} . '( ';
+ my $schema = $functions->{'namespace'};
+ my $comment = $functions->{'comment'};
+ my $functionargs = $functions->{'function_args'};
+ my @types = split( ' ', $functionargs );
+ my $count = 0;
+
+ # Pre-setup argument names when available.
+ my $argnames = $functions->{'function_arg_names'};
+ my @names;
+
+ if ( defined($argnames) ) {
+ $argnames =~ s/{(.*)}/$1/;
+ @names = split( ',', $argnames );
+ }
+
+ # Setup full argument types -- including the name prefix
+ foreach my $type (@types) {
+ $sth_FunctionArg->execute($type);
+
+ my $hash = $sth_FunctionArg->fetchrow_hashref;
+
+ if ( $count > 0 ) {
+ $functionname .= ', ';
+ }
+
+ if ( scalar(@names) > 0 ) {
+ $functionname .= $names[$count] . ' ';
+ }
+
+ if ( $hash->{'namespace'} ne $system_schema ) {
+ $functionname .= $hash->{'namespace'} . '.';
+ }
+ $functionname .= $hash->{'type_name'};
+
+ $count++;
+ }
+ $functionname .= ' )';
+
+ my $ret_type = $functions->{'returns_set'} ? 'SET OF ' : '';
+ $sth_FunctionArg->execute( $functions->{'return_type'} );
+ my $rhash = $sth_FunctionArg->fetchrow_hashref;
+ $ret_type .= $rhash->{'type_name'};
+
+ $struct->{$schema}{'FUNCTION'}{$functionname}{'COMMENT'} = $comment;
+ $struct->{$schema}{'FUNCTION'}{$functionname}{'SOURCE'} =
+ $functions->{'source_code'};
+ $struct->{$schema}{'FUNCTION'}{$functionname}{'LANGUAGE'} =
+ $functions->{'language_name'};
+ $struct->{$schema}{'FUNCTION'}{$functionname}{'RETURNS'} = $ret_type;
+ }
+
+ # Deal with the Schema
+ $sth_Schema->execute();
+ while ( my $schema = $sth_Schema->fetchrow_hashref ) {
+ my $comment = $schema->{'comment'};
+ my $namespace = $schema->{'namespace'};
+
+ $struct->{$namespace}{'SCHEMA'}{'COMMENT'} = $comment;
+ }
+
+ $sth_Columns->finish();
+ $sth_Constraint->finish();
+ $sth_Database->finish();
+ $sth_Foreign_Keys->finish();
+ $sth_Foreign_Key_Arg->finish();
+ $sth_Function->finish();
+ $sth_FunctionArg->finish();
+ $sth_Indexes->finish();
+ $sth_Inheritance->finish();
+ $sth_Primary_Keys->finish();
+ $sth_Schema->finish();
+ $sth_Tables->finish();
+ $sth_Table_Statistics->finish()
+ if ( $statistics == 1 );
+
+ $dbh->disconnect;
+
+} ## end sub info_collect($$$$$)
+
+#####
+# write_using_templates
+#
+# Generate structure that HTML::Template requires out of the
+# $struct for table related information, and $struct for
+# the schema and function information
+sub write_using_templates($$$$$) {
+ my ( $db, $database, $statistics, $template_path, $output_filename_base,
+ $wanted_output )
+ = @_;
+ my $struct = $db->{$database}{'STRUCT'};
+
+ my @schemas;
+
+ # Start at 0, increment to 1 prior to use.
+ my $object_id = 0;
+ my %tableids;
+ foreach my $schema ( sort keys %{$struct} ) {
+ my @tables;
+ foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) {
+
+ # Column List
+ my @columns;
+ foreach my $column (
+ sort {
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a}
+ {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table}
+ {'COLUMN'}{$b}{'ORDER'}
+ } keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} }
+ )
+ {
+ my $inferrednotnull = 0;
+
+ # Have a shorter default for places that require it
+ my $shortdefault =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'DEFAULT'};
+ $shortdefault =~ s/^(.{17}).{5,}(.{5})$/$1 ... $2/g
+ if ( defined($shortdefault) );
+
+ # Deal with column constraints
+ my @colconstraints;
+ foreach my $con (
+ sort keys %{
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}
+ }
+ )
+ {
+ if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'TYPE'} eq 'UNIQUE' )
+ {
+ my $unq =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'TYPE'};
+ my $unqcol =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'COLNUM'};
+ my $unqgroup =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'KEYGROUP'};
+
+ push @colconstraints,
+ {
+ column_unique => $unq,
+ column_unique_colnum => $unqcol,
+ column_unique_keygroup => $unqgroup,
+ };
+ }
+ elsif (
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'TYPE'} eq 'PRIMARY KEY' )
+ {
+ $inferrednotnull = 1;
+ push @colconstraints,
+ { column_primary_key => 'PRIMARY KEY', };
+ }
+ elsif (
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY' )
+ {
+ my $fksgmlid = sgml_safe_id(
+ join( '.',
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+ {$column}{'CON'}{$con}{'FKSCHEMA'},
+ $struct->{$schema}{'TABLE'}{$table}{'TYPE'},
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+ {$column}{'CON'}{$con}{'FKTABLE'} )
+ );
+
+ my $fkgroup =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'KEYGROUP'};
+ my $fktable =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'FKTABLE'};
+ my $fkcol =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'FK-COL NAME'};
+ my $fkschema =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'FKSCHEMA'};
+
+ push @colconstraints,
+ {
+ column_fk => 'FOREIGN KEY',
+ column_fk_colnum => $fkcol,
+ column_fk_keygroup => $fkgroup,
+ column_fk_schema => $fkschema,
+ column_fk_schema_dbk => docbook($fkschema),
+ column_fk_schema_dot => graphviz($fkschema),
+ column_fk_sgmlid => $fksgmlid,
+ column_fk_table => $fktable,
+ column_fk_table_dbk => docbook($fktable),
+ };
+
+ # only have the count if there is more than 1 schema
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $colconstraints[-1]{"number_of_schemas"} =
+ scalar( keys %{$struct} );
+ }
+ }
+ }
+
+ # Generate the Column array
+ push @columns, {
+ column => $column,
+ column_dbk => docbook($column),
+ column_dot => graphviz($column),
+ column_default =>
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'DEFAULT'},
+ column_default_dbk => docbook(
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'DEFAULT'}
+ ),
+ column_default_short => $shortdefault,
+ column_default_short_dbk => docbook($shortdefault),
+
+ column_comment =>
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'DESCRIPTION'},
+ column_comment_dbk => docbook(
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'DESCRIPTION'}
+ ),
+
+ column_number =>
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'ORDER'},
+
+ column_type =>
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'TYPE'},
+ column_type_dbk => docbook(
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'TYPE'}
+ ),
+ column_type_dot => graphviz(
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'TYPE'}
+ ),
+
+ column_constraints => \@colconstraints,
+ };
+
+ if ( $inferrednotnull == 0 ) {
+ $columns[-1]{"column_constraint_notnull"} =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'NULL'};
+ }
+ }
+
+ # Constraint List
+ my @constraints;
+ foreach my $constraint (
+ sort
+ keys %{ $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} }
+ )
+ {
+ my $shortcon =
+ $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'}
+ {$constraint};
+ $shortcon =~ s/^(.{30}).{5,}(.{5})$/$1 ... $2/g;
+ push @constraints,
+ {
+ constraint =>
+ $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'}
+ {$constraint},
+ constraint_dbk => docbook(
+ $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'}
+ {$constraint}
+ ),
+ constraint_name => $constraint,
+ constraint_name_dbk => docbook($constraint),
+ constraint_short => $shortcon,
+ constraint_short_dbk => docbook($shortcon),
+ table => $table,
+ table_dbk => docbook($table),
+ table_dot => graphviz($table),
+ };
+ }
+
+ # Index List
+ my @indexes;
+ foreach my $index (
+ sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INDEX'} } )
+ {
+ push @indexes,
+ {
+ index_definition =>
+ $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index},
+ index_definition_dbk => docbook(
+ $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index}
+ ),
+ index_name => $index,
+ index_name_dbk => docbook($index),
+ table => $table,
+ table_dbk => docbook($table),
+ table_dot => graphviz($table),
+ schema => $schema,
+ schema_dbk => docbook($schema),
+ schema_dot => graphviz($schema),
+ };
+ }
+
+ my @inherits;
+ foreach my $inhSch (
+ sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'} } )
+ {
+ foreach my $inhTab (
+ sort keys
+ %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'}{$inhSch} }
+ )
+ {
+ push @inherits,
+ {
+ table => $table,
+ table_dbk => docbook($table),
+ table_dot => graphviz($table),
+ schema => $schema,
+ schema_dbk => docbook($schema),
+ schema_dot => graphviz($schema),
+ sgmlid =>
+ sgml_safe_id( join( '.', $schema, 'table', $table ) ),
+ parent_sgmlid => sgml_safe_id(
+ join( '.', $inhSch, 'table', $inhTab )
+ ),
+ parent_table => $inhTab,
+ parent_table_dbk => docbook($inhTab),
+ parent_table_dot => graphviz($inhTab),
+ parent_schema => $inhSch,
+ parent_schema_dbk => docbook($inhSch),
+ parent_schema_dot => graphviz($inhSch),
+ };
+ }
+ }
+
+ # Foreign Key Discovery
+ #
+ # $lastmatch is used to ensure that we only supply a result a
+ # single time and not once for each link found. Since the
+ # loops are sorted, we only need to track the last element, and
+ # not all supplied elements.
+ my @fk_schemas;
+ my $lastmatch = '';
+ foreach my $fk_schema ( sort keys %{$struct} ) {
+ foreach
+ my $fk_table ( sort keys %{ $struct->{$fk_schema}{'TABLE'} } )
+ {
+ foreach my $fk_column (
+ sort keys
+ %{ $struct->{$fk_schema}{'TABLE'}{$fk_table}{'COLUMN'} }
+ )
+ {
+ foreach my $fk_con (
+ sort keys %{
+ $struct->{$fk_schema}{'TABLE'}{$fk_table}
+ {'COLUMN'}{$fk_column}{'CON'}
+ }
+ )
+ {
+ if ( $struct->{$fk_schema}{'TABLE'}{$fk_table}
+ {'COLUMN'}{$fk_column}{'CON'}{$fk_con}{'TYPE'}
+ eq 'FOREIGN KEY'
+ and $struct->{$fk_schema}{'TABLE'}{$fk_table}
+ {'COLUMN'}{$fk_column}{'CON'}{$fk_con}
+ {'FKTABLE'} eq $table
+ and $struct->{$fk_schema}{'TABLE'}{$fk_table}
+ {'COLUMN'}{$fk_column}{'CON'}{$fk_con}
+ {'FKSCHEMA'} eq $schema
+ and $lastmatch ne "$fk_schema$fk_table" )
+ {
+ my $fksgmlid = sgml_safe_id(
+ join( '.',
+ $fk_schema,
+ $struct->{$fk_schema}{'TABLE'}
+ {$fk_table}{'TYPE'},
+ $fk_table )
+ );
+ push @fk_schemas,
+ {
+ fk_column_number =>
+ $struct->{$fk_schema}{'TABLE'}{$fk_table}
+ {'COLUMN'}{$fk_column}{'ORDER'},
+ fk_sgmlid => $fksgmlid,
+ fk_schema => $fk_schema,
+ fk_schema_dbk => docbook($fk_schema),
+ fk_schema_dot => graphviz($fk_schema),
+ fk_table => $fk_table,
+ fk_table_dbk => docbook($fk_table),
+ fk_table_dot => graphviz($fk_table),
+ };
+
+ # only have the count if there is more than 1 schema
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $fk_schemas[-1]{"number_of_schemas"} =
+ scalar( keys %{$struct} );
+ }
+
+ $lastmatch = "$fk_schema$fk_table";
+ }
+ }
+ }
+ }
+ }
+
+ # List off permissions
+ my @permissions;
+ foreach my $user (
+ sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'} } )
+ {
+ push @permissions,
+ {
+ schema => $schema,
+ schema_dbk => docbook($schema),
+ schema_dot => graphviz($schema),
+ table => $table,
+ table_dbk => docbook($table),
+ table_dot => graphviz($table),
+ user => $user,
+ user_dbk => docbook($user),
+ };
+
+ # only have the count if there is more than 1 schema
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $permissions[-1]{"number_of_schemas"} =
+ scalar( keys %{$struct} );
+ }
+
+ foreach my $perm (
+ keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user} }
+ )
+ {
+ if ( $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user}
+ {$perm} == 1 )
+ {
+ $permissions[-1]{ lower($perm) } = 1;
+ }
+ }
+
+ }
+
+ # Increment and record the object ID
+ $tableids{"$schema$table"} = ++$object_id;
+ my $viewdef = sql_prettyprint(
+ $struct->{$schema}{'TABLE'}{$table}{'VIEW_DEF'} );
+
+ # Truncate comment for Dia
+ my $comment_dia =
+ $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'};
+ $comment_dia =~ s/^(.{35}).{5,}(.{5})$/$1 ... $2/g
+ if ( defined($comment_dia) );
+
+ push @tables, {
+ object_id => $object_id,
+ object_id_dbk => docbook($object_id),
+
+ schema => $schema,
+ schema_dbk => docbook($schema),
+ schema_dot => graphviz($schema),
+ schema_sgmlid => sgml_safe_id( $schema . ".schema" ),
+
+ # Statistics
+ stats_enabled => $statistics,
+ stats_dead_bytes => useUnits(
+ $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'}
+ ),
+ stats_dead_bytes_dbk => docbook(
+ useUnits(
+ $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'}
+ )
+ ),
+ stats_free_bytes =>
+ useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} ),
+ stats_free_bytes_dbk => docbook(
+ useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} )
+ ),
+ stats_table_bytes =>
+ useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} ),
+ stats_table_bytes_dbk => docbook(
+ useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} )
+ ),
+ stats_tuple_count =>
+ $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'},
+ stats_tuple_count_dbk =>
+ docbook( $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'} ),
+ stats_tuple_bytes =>
+ useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} ),
+ stats_tuple_bytes_dbk => docbook(
+ useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} )
+ ),
+
+ table => $table,
+ table_dbk => docbook($table),
+ table_dot => graphviz($table),
+ table_sgmlid => sgml_safe_id(
+ join( '.',
+ $schema, $struct->{$schema}{'TABLE'}{$table}{'TYPE'},
+ $table )
+ ),
+ table_comment =>
+ $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'},
+ table_comment_dbk =>
+ docbook( $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'} ),
+ table_comment_dia => $comment_dia,
+ view_definition => $viewdef,
+ view_definition_dbk => docbook($viewdef),
+ columns => \@columns,
+ constraints => \@constraints,
+ fk_schemas => \@fk_schemas,
+ indexes => \@indexes,
+ inherits => \@inherits,
+ permissions => \@permissions,
+ };
+
+ # only have the count if there is more than 1 schema
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $tables[-1]{"number_of_schemas"} = scalar( keys %{$struct} );
+ }
+ }
+
+ # Dump out list of functions
+ my @functions;
+ foreach my $function ( sort keys %{ $struct->{$schema}{'FUNCTION'} } ) {
+ push @functions,
+ {
+ function => $function,
+ function_dbk => docbook($function),
+ function_sgmlid =>
+ sgml_safe_id( join( '.', $schema, 'function', $function ) ),
+ function_comment =>
+ $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'},
+ function_comment_dbk => docbook(
+ $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'}
+ ),
+ function_language =>
+ uc( $struct->{$schema}{'FUNCTION'}{$function}{'LANGUAGE'} ),
+ function_returns =>
+ $struct->{$schema}{'FUNCTION'}{$function}{'RETURNS'},
+ function_source =>
+ $struct->{$schema}{'FUNCTION'}{$function}{'SOURCE'},
+ schema => $schema,
+ schema_dbk => docbook($schema),
+ schema_dot => graphviz($schema),
+ schema_sgmlid => sgml_safe_id( $schema . ".schema" ),
+ };
+
+ # only have the count if there is more than 1 schema
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $functions[-1]{"number_of_schemas"} = scalar( keys %{$struct} );
+ }
+ }
+
+ push @schemas,
+ {
+ schema => $schema,
+ schema_dbk => docbook($schema),
+ schema_dot => graphviz($schema),
+ schema_sgmlid => sgml_safe_id( $schema . ".schema" ),
+ schema_comment => $struct->{$schema}{'SCHEMA'}{'COMMENT'},
+ schema_comment_dbk =>
+ docbook( $struct->{$schema}{'SCHEMA'}{'COMMENT'} ),
+ functions => \@functions,
+ tables => \@tables,
+ };
+
+ # Build the array of schemas
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $schemas[-1]{"number_of_schemas"} = scalar( keys %{$struct} );
+ }
+ }
+
+ # Link the various components together via the template.
+ my @fk_links;
+ my @fkeys;
+ foreach my $schema ( sort keys %{$struct} ) {
+ foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) {
+ foreach my $column (
+ sort {
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a}
+ {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table}
+ {'COLUMN'}{$b}{'ORDER'}
+ }
+ keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} }
+ )
+ {
+ foreach my $con (
+ sort keys %{
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}
+ }
+ )
+ {
+
+ # To prevent a multi-column foreign key from appearing
+ # several times, we've opted
+ # to simply display the first column of any given key.
+ # Since column numbering always starts at 1
+ # for foreign keys.
+ if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY'
+ && $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+ {$column}{'CON'}{$con}{'COLNUM'} == 1 )
+ {
+
+ # Pull out some of the longer keys
+ my $ref_table =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'FKTABLE'};
+ my $ref_schema =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'FKSCHEMA'};
+ my $ref_column =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+ {'CON'}{$con}{'FK-COL NAME'};
+
+ # Default values cause these elements to attach
+ # to the bottom in Dia
+ # If a KEYGROUP is not defined, it's a single column.
+ # Modify the ref_con and key_con variables to attach
+ # the to the columns connection point directly.
+ my $ref_con = 0;
+ my $key_con = 0;
+ my $keycon_offset = 0;
+ if (
+ !defined(
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+ {$column}{'CON'}{$con}{'KEYGROUP'}
+ )
+ )
+ {
+ $ref_con =
+ $struct->{$ref_schema}{'TABLE'}{$ref_table}
+ {'COLUMN'}{$ref_column}{'ORDER'} || 0;
+ $key_con =
+ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+ {$column}{'ORDER'} || 0;
+ $keycon_offset = 1;
+ }
+
+ # Bump object_id
+ $object_id++;
+
+ push @fk_links,
+ {
+ fk_link_name => $con,
+ fk_link_name_dbk => docbook($con),
+ fk_link_name_dot => graphviz($con),
+ handle0_connection => $key_con,
+ handle0_connection_dbk => docbook($key_con),
+ handle0_connection_dia => 6 + ( $key_con * 2 ),
+ handle0_name => $table,
+ handle0_name_dbk => docbook($table),
+ handle0_schema => $schema,
+ handle0_to => $tableids{"$schema$table"},
+ handle0_to_dbk =>
+ docbook( $tableids{"$schema$table"} ),
+ handle1_connection => $ref_con,
+ handle1_connection_dbk => docbook($ref_con),
+ handle1_connection_dia => 6 +
+ ( $ref_con * 2 ) +
+ $keycon_offset,
+ handle1_name => $ref_table,
+ handle1_name_dbk => docbook($ref_table),
+ handle1_schema => $ref_schema,
+ handle1_to => $tableids{"$ref_schema$ref_table"},
+ handle1_to_dbk =>
+ docbook( $tableids{"$ref_schema$ref_table"} ),
+ object_id => $object_id,
+ object_id_dbk => docbook($object_id),
+ };
+
+ # Build the array of schemas
+ if ( scalar( keys %{$struct} ) > 1 ) {
+ $fk_links[-1]{"number_of_schemas"} =
+ scalar( keys %{$struct} );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ # Make database level comment information
+ my @timestamp = localtime();
+ my $dumped_on = sprintf( "%04d-%02d-%02d",
+ $timestamp[5] + 1900,
+ $timestamp[4] + 1,
+ $timestamp[3] );
+ my $database_comment = $db->{$database}{'COMMENT'};
+
+ # Loop through each template found in the supplied path.
+ # Output the results of the template as <filename>.<extension>
+ # into the current working directory.
+ my @template_files = glob( $template_path . '/*.tmpl' );
+
+ # Ensure we've told the user if we don't find any files.
+ triggerError("Templates files not found in $template_path")
+ if ( $#template_files < 0 );
+
+ # Process all found templates.
+ foreach my $template_file (@template_files) {
+ ( my $file_extension = $template_file ) =~
+ s/^(?:.*\/|)([^\/]+)\.tmpl$/$1/;
+ next
+ if ( defined($wanted_output) && $file_extension ne $wanted_output );
+ my $output_filename = "$output_filename_base.$file_extension";
+ print "Producing $output_filename from $template_file\n";
+
+ my $template = HTML::Template->new(
+ filename => $template_file,
+ die_on_bad_params => 0,
+ global_vars => 0,
+ strict => 1,
+ loop_context_vars => 1
+ );
+
+ $template->param(
+ database => $database,
+ database_dbk => docbook($database),
+ database_sgmlid => sgml_safe_id($database),
+ database_comment => $database_comment,
+ database_comment_dbk => docbook($database_comment),
+ dumped_on => $dumped_on,
+ dumped_on_dbk => docbook($dumped_on),
+ fk_links => \@fk_links,
+ schemas => \@schemas,
+ );
+
+ sysopen( FH, $output_filename, O_WRONLY | O_TRUNC | O_CREAT, 0644 )
+ or die "Can't open $output_filename: $!";
+ print FH $template->output();
+ }
+} ## end sub write_using_templates($$$$$)
+
+######
+# sgml_safe_id
+# Safe SGML ID Character replacement
+sub sgml_safe_id($) {
+ my $string = shift;
+
+ # Lets use the keyword ARRAY in place of the square brackets
+ # to prevent duplicating a non-array equivelent
+ $string =~ s/\[\]/ARRAY-/g;
+
+ # Brackets, spaces, commads, underscores are not valid 'id' characters
+ # replace with as few -'s as possible.
+ $string =~ s/[ "',)(_-]+/-/g;
+
+ # Don't want a - at the end either. It looks silly.
+ $string =~ s/-$//g;
+
+ return ($string);
+}
+
+#####
+# lower
+# LowerCase the string
+sub lower($) {
+ my $string = shift;
+
+ $string =~ tr/A-Z/a-z/;
+
+ return ($string);
+}
+
+#####
+# useUnits
+# Tack on base 2 metric units
+sub useUnits($) {
+ my ($value) = @_;
+
+ return '' if ( !defined($value) );
+
+ my @units = ( 'Bytes', 'KiBytes', 'MiBytes', 'GiBytes', 'TiBytes' );
+ my $loop = 0;
+
+ while ( $value >= 1024 ) {
+ $loop++;
+
+ $value = $value / 1024;
+ }
+
+ return ( sprintf( "%.2f %s", $value, $units[$loop] ) );
+}
+
+#####
+# docbook
+# Docbook output is special in that we may or may not want to escape
+# the characters inside the string depending on a string prefix.
+sub docbook($) {
+ my $string = shift;
+
+ if ( defined($string) ) {
+ if ( $string =~ /^\@DOCBOOK/ ) {
+ $string =~ s/^\@DOCBOOK//;
+ }
+ else {
+ $string =~ s/&(?!(amp|lt|gr|apos|quot);)/&amp;/g;
+ $string =~ s/</&lt;/g;
+ $string =~ s/>/&gt;/g;
+ $string =~ s/'/&apos;/g;
+ $string =~ s/"/&quot;/g;
+ }
+ }
+ else {
+
+ # Return an empty string when all else fails
+ $string = '';
+ }
+
+ return ($string);
+}
+
+#####
+# graphviz
+# GraphViz output requires that special characters (like " and whitespace) must be preceeded
+# by a \ when a part of a lable.
+sub graphviz($) {
+ my $string = shift;
+
+ # Ensure we don't return an least a empty string
+ $string = '' if ( !defined($string) );
+
+ $string =~ s/([\s"'])/\\$1/g;
+
+ return ($string);
+}
+
+#####
+# sql_prettyprint
+# Clean up SQL into something presentable
+sub sql_prettyprint($) {
+ my $string = shift;
+
+ # If nothing has been sent in, return an empty string
+ if ( !defined($string) ) {
+ return '';
+ }
+
+ # Initialize Result string
+ my $result = '';
+
+ # List of tokens to split on
+ my $tok =
+ "SELECT|FROM|WHERE|HAVING|GROUP BY|ORDER BY|OR|AND|LEFT JOIN|RIGHT JOIN"
+ . "|LEFT OUTER JOIN|LEFT INNER JOIN|INNER JOIN|RIGHT OUTER JOIN|RIGHT INNER JOIN"
+ . "|JOIN|UNION ALL|UNION|EXCEPT|USING|ON|CAST|[\(\),]";
+
+ my $key = 0;
+ my $bracket = 0;
+ my $depth = 0;
+ my $indent = 6;
+
+ # XXX: Split is wrong -- match would do
+ foreach my $elem ( split( /(\"[^\"]*\"|'[^']*'|$tok)/, $string ) ) {
+ my $format;
+
+ # Skip junk tokens
+ if ( $elem =~ /^[\s]?$/ ) {
+ next;
+ }
+
+ # NOTE: Should we drop leading spaces?
+ # $elem =~ s/^\s//;
+
+ # Close brackets are special
+ # Bring depth in a level
+ if ( $elem =~ /\)/ ) {
+ $depth = $depth - $indent;
+ if ( $key == 1 or $bracket == 1 ) {
+ $format = "%s%s";
+ }
+ else {
+ $format = "%s\n%" . $depth . "s";
+ }
+
+ $key = 0;
+ $bracket = 0;
+ }
+
+ # Open brackets are special
+ # Bump depth out a level
+ elsif ( $elem =~ /\(/ ) {
+ if ( $key == 1 ) {
+ $format = "%s %s";
+ }
+ else {
+ $format = "%s\n%" . $depth . "s";
+ }
+ $depth = $depth + $indent;
+ $bracket = 1;
+ $key = 0;
+ }
+
+ # Key element
+ # Token from our list -- format on left hand side of the equation
+ # when appropriate.
+ elsif ( $elem =~ /$tok/ ) {
+ if ( $key == 1 ) {
+ $format = "%s%s";
+ }
+ else {
+ $format = "%s\n%" . $depth . "s";
+ }
+
+ $key = 1;
+ $bracket = 0;
+ }
+
+ # Value
+ # Format for right hand side of the equation
+ else {
+ $format = "%s%s";
+
+ $key = 0;
+ }
+
+ # Add the new format string to the result
+ $result = sprintf( $format, $result, $elem );
+ }
+
+ return $result;
+} ## end sub sql_prettyprint($)
+
+##
+# triggerError
+# Print out a supplied error message and exit the script.
+sub triggerError($) {
+ my ($error) = @_;
+
+ # Test error
+ if ( !defined($error) || $error eq '' ) {
+
+ # Suppress prototype checking in call to self
+ &triggerError("triggerError: Unknown error");
+ }
+ printf( "\n\n%s\n", $error );
+
+ exit 2;
+}
+
+#####
+# usage
+sub usage($$$) {
+ my ( $basename, $database, $dbuser ) = @_;
+ print <<USAGE
+Usage:
+ $basename [options] [dbname [username]]
+
+Options:
+ -d <dbname> Specify database name to connect to (default: $database)
+ -f <file> Specify output file prefix (default: $database)
+ -h <host> Specify database server host (default: localhost)
+ -p <port> Specify database server port (default: 5432)
+ -u <username> Specify database username (default: $dbuser)
+ --password=<pw> Specify database password (default: blank)
+ --password Have $basename prompt for a password
+
+ -l <path> Path to the templates (default: @@TEMPLATE-DIR@@)
+ -t <output> Type of output wanted (default: All in template library)
+
+ -s <schema> Specify a specific schema to match. Technically this is a regular
+ expression but anything other than a specific name may have unusual
+ results.
+ --table=<args> Tables to export. Multiple tables may be provided using a
+ comma-separated list.
+
+ --statistics In 7.4 and later, with the contrib module pgstattuple installed we
+ can gather statistics on the tables in the database
+ (average size, free space, disk space used, dead tuple counts, etc.)
+ This is disk intensive on large databases as all pages must be visited.
+USAGE
+ ;
+ exit 1;
+}
+
+sub single_quote {
+ my $attr = $_;
+ $attr =~ s/^\s+|\s+$//g;
+ return qq{'$attr'};
+}
+
+##
+# Kick off execution of main()
+main($ARGV);
+
diff --git a/postgresql_autodoc/xml.tmpl b/postgresql_autodoc/xml.tmpl
new file mode 100644
index 0000000..d589930
--- /dev/null
+++ b/postgresql_autodoc/xml.tmpl
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- $Header: /cvsroot/autodoc/autodoc/xml.tmpl,v 1.2 2006/05/16 19:01:27 rbt Exp $ -->
+
+<book id="database.<!-- TMPL_VAR name="database_sgmlid" -->" xreflabel="<!-- TMPL_VAR name="database_dbk" --> database schema"><title><!-- TMPL_VAR name="database_dbk" --> Model</title>
+
+<!-- TMPL_IF name="database_comment" -->
+<!-- TMPL_VAR name="database_comment_dbk" -->
+<!-- /TMPL_IF name="database_comment" -->
+
+<!-- TMPL_LOOP name="schemas" -->
+ <chapter id="<!-- TMPL_VAR name="schema_sgmlid" -->"
+ xreflabel="<!-- TMPL_VAR name="schema_dbk" -->">
+ <title>Schema <!-- TMPL_VAR name="schema_dbk" --></title>
+ <para><!-- TMPL_VAR name="schema_comment_dbk" --></para>
+
+<!-- TMPL_LOOP name="tables" -->
+ <section id="<!-- TMPL_VAR name="table_sgmlid" -->"
+ xreflabel="<!-- TMPL_VAR name="schema_dbk" -->.<!-- TMPL_VAR name="table_dbk" -->">
+ <title id="<!-- TMPL_VAR name="table_sgmlid" -->-title">
+ <!-- TMPL_IF name="view_definition" -->View:
+ <!-- TMPL_ELSE -->Table:
+ <!-- /TMPL_IF name="view_definition" -->
+ <structname><!-- TMPL_VAR name="table_dbk" --></structname>
+ </title>
+
+<!-- TMPL_IF name="table_comment" -->
+ <para>
+ <!-- TMPL_VAR name="table_comment_dbk" -->
+ </para>
+<!-- /TMPL_IF name="table_comment" -->
+
+ <para>
+ <variablelist>
+ <title>
+ Structure of <structname><!-- TMPL_VAR name="table_dbk" --></structname>
+ </title>
+
+<!-- TMPL_LOOP name="columns" -->
+ <varlistentry>
+ <term><structfield><!-- TMPL_VAR name="column_dbk" --></structfield></term>
+ <listitem><para>
+ <type><!-- TMPL_VAR name="column_type_dbk" --></type>
+<!-- TMPL_LOOP name="column_constraints" -->
+<!-- TMPL_IF name="column_primary_key" -->
+ <literal>PRIMARY KEY</literal>
+
+<!-- /TMPL_IF name="column_primary_key" -->
+
+<!-- TMPL_IF name="column_unique" -->
+ <literal>UNIQUE<!-- TMPL_IF name="column_unique_keygroup" -->#<!-- TMPL_VAR name="column_unique_keygroup" --><!-- /TMPL_IF name="column_unique_keygroup" --></literal>
+<!-- /TMPL_IF name="column_unique" -->
+<!-- /TMPL_LOOP name="column_constraints" -->
+
+<!-- TMPL_IF name="column_constraint_notnull" -->
+ <literal>NOT NULL</literal>
+<!-- /TMPL_IF name="column_constraint_notnull" -->
+
+<!-- TMPL_IF name="column_default" -->
+ <literal>DEFAULT <!-- TMPL_VAR name="column_default_dbk" --></literal>
+<!-- /TMPL_IF name="column_default" -->
+
+<!-- TMPL_LOOP name="column_constraints" -->
+<!-- TMPL_IF name="column_fk" -->
+ <literal>REFERENCES</literal> <xref linkend="<!-- TMPL_VAR name="column_fk_sgmlid" -->"/>
+<!-- /TMPL_IF name="column_fk" -->
+<!-- /TMPL_LOOP name="column_constraints" -->
+ </para>
+<!-- TMPL_IF name="column_comment" -->
+ <para>
+ <!-- TMPL_VAR name="column_comment_dbk" -->
+ </para>
+<!-- /TMPL_IF name="column_comment" -->
+ </listitem>
+ </varlistentry>
+<!-- /TMPL_LOOP name="columns" -->
+ </variablelist>
+
+<!-- TMPL_LOOP name="constraints" -->
+<!-- TMPL_IF name="__FIRST__" -->
+ <variablelist>
+ <title>Constraints on <!-- TMPL_VAR name="table_dbk" --></title>
+<!-- /TMPL_IF name="__FIRST__" -->
+ <varlistentry>
+ <term><!-- TMPL_VAR name="constraint_name_dbk" --></term>
+ <listitem><para><!-- TMPL_VAR name="constraint_dbk" --></para></listitem>
+ </varlistentry>
+<!-- TMPL_IF name="__LAST__" -->
+ </variablelist>
+<!-- /TMPL_IF name="__LAST__" -->
+<!-- /TMPL_LOOP name="constraints" -->
+
+<!-- TMPL_LOOP name="indexes" -->
+<!-- TMPL_IF name="__FIRST__" -->
+ <variablelist>
+ <title>Indexes on <!-- TMPL_VAR name="table_dbk" --></title>
+<!-- /TMPL_IF name="__FIRST__" -->
+ <varlistentry>
+ <term><!-- TMPL_VAR name="index_name_dbk" --></term>
+ <listitem><para><!-- TMPL_VAR name="index_definition_dbk" --></para></listitem>
+ </varlistentry>
+<!-- TMPL_IF name="__LAST__" -->
+ </variablelist>
+<!-- /TMPL_IF name="__LAST__" -->
+<!-- /TMPL_LOOP name="indexes" -->
+
+<!-- TMPL_LOOP name="fk_schemas" -->
+<!-- TMPL_IF name="__FIRST__" -->
+ <itemizedlist>
+ <title>
+ Tables referencing <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_schema_dbk" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_table_dbk" --> via Foreign Key Constraints
+ </title>
+<!-- /TMPL_IF name="__FIRST__" -->
+ <listitem>
+ <para>
+ <xref linkend="<!-- TMPL_VAR name="fk_sgmlid" -->"/>
+ </para>
+ </listitem>
+<!-- TMPL_IF name="__LAST__" -->
+ </itemizedlist>
+<!-- /TMPL_IF name="__LAST__" -->
+<!-- /TMPL_LOOP name="fk_schemas" -->
+
+<!-- TMPL_IF name="view_definition" -->
+ <figure>
+ <title>Definition of view <!-- TMPL_VAR name="table_dbk" --></title>
+ <programlisting><!-- TMPL_VAR name="view_definition_dbk" --></programlisting>
+ </figure>
+<!-- /TMPL_IF name="view_definition" -->
+<!-- TMPL_LOOP name="permissions" -->
+<!-- TMPL_IF name="__FIRST__" -->
+ <variablelist>
+ <title>Permissions on <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR name="table_dbk" --></title>
+<!-- /TMPL_IF name="__FIRST__" -->
+ <varlistentry>
+ <term><!-- TMPL_VAR name="user_dbk" --></term>
+ <listitem>
+ <para>
+ <simplelist type="inline">
+<!-- TMPL_IF name="select" -->
+ <member>Select</member>
+<!-- /TMPL_IF name="select" -->
+<!-- TMPL_IF name="insert" -->
+ <member>Insert</member>
+<!-- /TMPL_IF name="insert" -->
+<!-- TMPL_IF name="update" -->
+ <member>Update</member>
+<!-- /TMPL_IF name="update" -->
+<!-- TMPL_IF name="delete" -->
+ <member>Delete</member>
+<!-- /TMPL_IF name="delete" -->
+<!-- TMPL_IF name="rule" -->
+ <member>Rule</member>
+<!-- /TMPL_IF name="rule" -->
+<!-- TMPL_IF name="references" -->
+ <member>References</member>
+<!-- /TMPL_IF name="references" -->
+<!-- TMPL_IF name="trigger" -->
+ <member>Trigger</member>
+<!-- /TMPL_IF name="trigger" -->
+ </simplelist>
+ </para>
+ </listitem>
+ </varlistentry>
+<!-- TMPL_IF name="__LAST__" -->
+ </variablelist>
+<!-- /TMPL_IF name="__LAST__" -->
+<!-- /TMPL_LOOP name="permissions" -->
+
+ </para>
+ </section>
+<!-- /TMPL_LOOP name="tables" -->
+
+<!-- TMPL_LOOP name="functions" -->
+<!-- Function <!-- TMPL_VAR NAME="function" --> -->
+ <section id="<!-- TMPL_VAR NAME="function_sgmlid" -->"
+ xreflabel="<!-- TMPL_VAR NAME="schema_dbk" --><!-- TMPL_VAR NAME="function_dbk"-->">
+ <title id="<!-- TMPL_VAR NAME="function_sgmlid" -->-title">
+ <!-- TMPL_VAR name="function_dbk" -->
+ </title>
+ <titleabbrev id="<!-- TMPL_VAR NAME="function_sgmlid" -->-titleabbrev">
+ <!-- TMPL_VAR name="function_dbk" -->
+ </titleabbrev>
+
+ <para>
+ <segmentedlist>
+ <title>Function Properties</title>
+ <?dbhtml list-presentation="list"?>
+ <segtitle>Language</segtitle>
+ <segtitle>Return Type</segtitle>
+ <seglistitem>
+ <seg><!-- TMPL_VAR ESCAPE="HTML" name="function_language" --></seg>
+ <seg><!-- TMPL_VAR ESCAPE="HTML" name="function_returns" --></seg>
+ </seglistitem>
+ </segmentedlist>
+
+ <!-- TMPL_VAR name="function_comment_dbk" -->
+ <programlisting><!-- TMPL_IF name="function_source" --><!-- TMPL_VAR ESCAPE="HTML" name="function_source" --><!-- /TMPL_IF name="function_source" --></programlisting>
+ </para>
+ </section>
+<!-- /TMPL_LOOP name="functions" -->
+ </chapter>
+<!-- /TMPL_LOOP name="schemas" -->
+</book>
+
diff --git a/postgresql_autodoc/zigzag.dia.tmpl b/postgresql_autodoc/zigzag.dia.tmpl
new file mode 100644
index 0000000..2b9f952
--- /dev/null
+++ b/postgresql_autodoc/zigzag.dia.tmpl
@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
+ <dia:layer name="Background" visible="true">
+<!-- TMPL_LOOP name="schemas" -->
+<!-- TMPL_IF name="number_of_schemas" -->
+ <dia:group>
+<!-- /TMPL_IF name="number_of_schemas" -->
+<!-- TMPL_LOOP name="tables" -->
+ <dia:object type="UML - Class" version="0" id="O<!-- TMPL_VAR ESCAPE="HTML" name="object_id" -->">
+ <dia:attribute name="obj_pos">
+ <dia:point val="0,0"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-0.05,-0.05;16.4,6.65"/>
+ </dia:attribute>
+ <dia:attribute name="elem_corner">
+ <dia:point val="0,0"/>
+ </dia:attribute>
+ <dia:attribute name="elem_width">
+ <dia:real val="16.350000000000001"/>
+ </dia:attribute>
+ <dia:attribute name="elem_height">
+ <dia:real val="6.6000000000000005"/>
+ </dia:attribute>
+ <dia:attribute name="name">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="table" -->#</dia:string>
+ </dia:attribute>
+<!-- TMPL_IF name="number_of_schemas" -->
+ <dia:attribute name="stereotype">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="schema" -->#</dia:string>
+ </dia:attribute>
+<!-- /TMPL_IF name="number_of_schemas" -->
+ <dia:attribute name="comment">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="table_comment_dia" -->#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="abstract">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="suppress_attributes">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="suppress_operations">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="visible_attributes">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="visible_comments">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="wrap_operations">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="wrap_after_char">
+ <dia:int val="40"/>
+ </dia:attribute>
+ <dia:attribute name="line_color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="fill_color">
+ <dia:color val="#ffffff"/>
+ </dia:attribute>
+ <dia:attribute name="text_color">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="normal_font">
+ <dia:font family="monospace" style="0" name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="abstract_font">
+ <dia:font family="monospace" style="88" name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="polymorphic_font">
+ <dia:font family="monospace" style="8" name="Courier"/>
+ </dia:attribute>
+ <dia:attribute name="classname_font">
+ <dia:font family="sans" style="80" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="abstract_classname_font">
+ <dia:font family="sans" style="88" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="comment_font">
+ <dia:font family="sans" style="8" name="Helvetica"/>
+ </dia:attribute>
+ <dia:attribute name="font_height">
+ <dia:real val="0.80000000000000004"/>
+ </dia:attribute>
+ <dia:attribute name="polymorphic_font_height">
+ <dia:real val="0.80000000000000004"/>
+ </dia:attribute>
+ <dia:attribute name="abstract_font_height">
+ <dia:real val="0.80000000000000004"/>
+ </dia:attribute>
+ <dia:attribute name="classname_font_height">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="abstract_classname_font_height">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="comment_font_height">
+ <dia:real val="1"/>
+ </dia:attribute>
+ <dia:attribute name="attributes">
+<!-- TMPL_LOOP name="columns" -->
+ <dia:composite type="umlattribute">
+ <dia:attribute name="name">
+ <dia:string>#<!-- TMPL_IF name="column_primary_key" -->PK<!-- TMPL_ELSE name="column_primary_key" --> <!-- /TMPL_IF name="column_primary_key" --><!-- TMPL_VAR ESCAPE="HTML" name="column" -->#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="type">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="column_type" -->#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="value">
+<!-- TMPL_IF name="column_default_short" -->
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="column_default_short" -->#</dia:string>
+<!-- TMPL_ELSE name="column_default_short" -->
+ <dia:string/>
+<!-- /TMPL_IF name="column_default_short" -->
+ </dia:attribute>
+ <dia:attribute name="visibility">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ <dia:attribute name="abstract">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="class_scope">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ </dia:composite>
+<!-- /TMPL_LOOP name="columns" -->
+ </dia:attribute>
+<!-- TMPL_IF name="constraints" -->
+ <dia:attribute name="visible_operations">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:attribute name="operations">
+<!-- TMPL_LOOP name="constraints" -->
+ <dia:composite type="umloperation">
+ <dia:attribute name="name">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="constraint_name" -->#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="visibility">
+ <dia:enum val="3"/>
+ </dia:attribute>
+ <dia:attribute name="abstract">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="class_scope">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="parameters">
+ <dia:composite type="umlparameter">
+ <dia:attribute name="name">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="constraint_short" -->#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="type">
+ <dia:string>##</dia:string>
+ </dia:attribute>
+ <dia:attribute name="value">
+ <dia:string/>
+ </dia:attribute>
+ <dia:attribute name="kind">
+ <dia:enum val="0"/>
+ </dia:attribute>
+ </dia:composite>
+ </dia:attribute>
+ </dia:composite>
+<!-- /TMPL_LOOP name="constraints" -->
+ </dia:attribute>
+<!-- TMPL_ELSE name="constraints" -->
+ <dia:attribute name="visible_operations">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="operations"/>
+<!-- /TMPL_IF name="constraints" -->
+ <dia:attribute name="template">
+ <dia:boolean val="false"/>
+ </dia:attribute>
+ <dia:attribute name="templates"/>
+ </dia:object>
+<!-- /TMPL_LOOP name="tables" -->
+<!-- TMPL_IF name="number_of_schemas" -->
+ </dia:group>
+<!-- /TMPL_IF name="number_of_schemas" -->
+<!-- /TMPL_LOOP name="schemas" -->
+<!-- TMPL_LOOP name="fk_links" -->
+ <dia:object type="UML - Dependency" version="0" id="O<!-- TMPL_VAR ESCAPE="HTML" name="object_id" -->">
+ <dia:attribute name="obj_pos">
+ <dia:point val="0,3.5"/>
+ </dia:attribute>
+ <dia:attribute name="obj_bb">
+ <dia:rectangle val="-0.0515705,2.29861;25.1127,3.55157"/>
+ </dia:attribute>
+ <dia:attribute name="orth_points">
+ <dia:point val="1.0,1.0"/>
+ <dia:point val="1.0,1.0"/>
+ <dia:point val="1.0,1.0"/>
+ </dia:attribute>
+ <dia:attribute name="orth_orient">
+ <dia:enum val="1"/>
+ <dia:enum val="0"/>
+ </dia:attribute>
+ <dia:attribute name="orth_autoroute">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+
+ <dia:attribute name="line_colour">
+ <dia:color val="#000000"/>
+ </dia:attribute>
+ <dia:attribute name="name">
+ <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="fk_link_name" -->#</dia:string>
+ </dia:attribute>
+ <dia:attribute name="stereotype">
+ <dia:string>##</dia:string>
+ </dia:attribute>
+ <dia:attribute name="draw_arrow">
+ <dia:boolean val="true"/>
+ </dia:attribute>
+ <dia:connections>
+ <dia:connection handle="0" to="O<!-- TMPL_VAR ESCAPE="HTML" name="handle0_to" -->" connection="<!-- TMPL_VAR ESCAPE="HTML" name="handle0_connection_dia" -->"/>
+ <dia:connection handle="1" to="O<!-- TMPL_VAR ESCAPE="HTML" name="handle1_to" -->" connection="<!-- TMPL_VAR ESCAPE="HTML" name="handle1_connection_dia" -->"/>
+ </dia:connections>
+ </dia:object>
+<!-- /TMPL_LOOP name="fk_links" -->
+ </dia:layer>
+</dia:diagram>