216 lines
4.6 KiB
Perl
216 lines
4.6 KiB
Perl
#! /usr/bin/perl -w
|
|
|
|
#################################################################
|
|
# create_help.pl -- converts SGML docs to internal psql help
|
|
#
|
|
# Copyright (c) 2000-2012, PostgreSQL Global Development Group
|
|
#
|
|
# src/bin/psql/create_help.pl
|
|
#################################################################
|
|
|
|
#
|
|
# This script automatically generates the help on SQL in psql from
|
|
# the SGML docs. So far the format of the docs was consistent
|
|
# enough that this worked, but this here is by no means an SGML
|
|
# parser.
|
|
#
|
|
# Call: perl create_help.pl docdir sql_help
|
|
# The name of the header file doesn't matter to this script, but it
|
|
# sure does matter to the rest of the source.
|
|
#
|
|
|
|
use strict;
|
|
|
|
my $docdir = $ARGV[0] or die "$0: missing required argument: docdir\n";
|
|
my $hfile = $ARGV[1] . '.h'
|
|
or die "$0: missing required argument: output file\n";
|
|
my $cfile = $ARGV[1] . '.c';
|
|
|
|
my $hfilebasename;
|
|
if ($hfile =~ m!.*/([^/]+)$!)
|
|
{
|
|
$hfilebasename = $1;
|
|
}
|
|
else
|
|
{
|
|
$hfilebasename = $hfile;
|
|
}
|
|
|
|
my $define = $hfilebasename;
|
|
$define =~ tr/a-z/A-Z/;
|
|
$define =~ s/\W/_/g;
|
|
|
|
opendir(DIR, $docdir)
|
|
or die "$0: could not open documentation source dir '$docdir': $!\n";
|
|
open(HFILE, ">$hfile")
|
|
or die "$0: could not open output file '$hfile': $!\n";
|
|
open(CFILE, ">$cfile")
|
|
or die "$0: could not open output file '$cfile': $!\n";
|
|
|
|
print HFILE "/*
|
|
* *** Do not change this file by hand. It is automatically
|
|
* *** generated from the DocBook documentation.
|
|
*
|
|
* generated by
|
|
* $^X $0 @ARGV
|
|
*
|
|
*/
|
|
|
|
#ifndef $define
|
|
#define $define
|
|
|
|
#define N_(x) (x) /* gettext noop */
|
|
|
|
#include \"postgres_fe.h\"
|
|
#include \"pqexpbuffer.h\"
|
|
|
|
struct _helpStruct
|
|
{
|
|
const char *cmd; /* the command name */
|
|
const char *help; /* the help associated with it */
|
|
void (*syntaxfunc)(PQExpBuffer); /* function that prints the syntax associated with it */
|
|
int nl_count; /* number of newlines in syntax (for pager) */
|
|
};
|
|
|
|
";
|
|
|
|
print CFILE "/*
|
|
* *** Do not change this file by hand. It is automatically
|
|
* *** generated from the DocBook documentation.
|
|
*
|
|
* generated by
|
|
* $^X $0 @ARGV
|
|
*
|
|
*/
|
|
|
|
#include \"$hfile\"
|
|
|
|
";
|
|
|
|
my $maxlen = 0;
|
|
|
|
my %entries;
|
|
|
|
foreach my $file (sort readdir DIR)
|
|
{
|
|
my (@cmdnames, $cmddesc, $cmdsynopsis);
|
|
$file =~ /\.sgml$/ or next;
|
|
|
|
open(FILE, "$docdir/$file") or next;
|
|
my $filecontent = join('', <FILE>);
|
|
close FILE;
|
|
|
|
# Ignore files that are not for SQL language statements
|
|
$filecontent =~
|
|
m!<refmiscinfo>\s*SQL - Language Statements\s*</refmiscinfo>!i
|
|
or next;
|
|
|
|
# Collect multiple refnames
|
|
LOOP:
|
|
{
|
|
$filecontent =~ m!\G.*?<refname>\s*([a-z ]+?)\s*</refname>!cgis
|
|
and push @cmdnames, $1
|
|
and redo LOOP;
|
|
}
|
|
$filecontent =~ m!<refpurpose>\s*(.+?)\s*</refpurpose>!is
|
|
and $cmddesc = $1;
|
|
$filecontent =~ m!<synopsis>\s*(.+?)\s*</synopsis>!is
|
|
and $cmdsynopsis = $1;
|
|
|
|
if (@cmdnames && $cmddesc && $cmdsynopsis)
|
|
{
|
|
s/\"/\\"/g foreach @cmdnames;
|
|
|
|
$cmddesc =~ s/<[^>]+>//g;
|
|
$cmddesc =~ s/\s+/ /g;
|
|
$cmddesc =~ s/\"/\\"/g;
|
|
|
|
my @params = ();
|
|
|
|
my $nl_count = () = $cmdsynopsis =~ /\n/g;
|
|
|
|
$cmdsynopsis =~ m!</>!
|
|
and die "$0:$file: null end tag not supported in synopsis\n";
|
|
$cmdsynopsis =~ s/%/%%/g;
|
|
|
|
while ($cmdsynopsis =~ m!<(\w+)[^>]*>(.+?)</\1[^>]*>!)
|
|
{
|
|
my $match = $2;
|
|
$match =~ s/<[^>]+>//g;
|
|
$match =~ s/%%/%/g;
|
|
push @params, $match;
|
|
$cmdsynopsis =~ s!<(\w+)[^>]*>.+?</\1[^>]*>!%s!;
|
|
}
|
|
$cmdsynopsis =~ s/\r?\n/\\n/g;
|
|
$cmdsynopsis =~ s/\"/\\"/g;
|
|
|
|
foreach my $cmdname (@cmdnames)
|
|
{
|
|
$entries{$cmdname} = {
|
|
cmddesc => $cmddesc,
|
|
cmdsynopsis => $cmdsynopsis,
|
|
params => \@params,
|
|
nl_count => $nl_count };
|
|
$maxlen =
|
|
($maxlen >= length $cmdname) ? $maxlen : length $cmdname;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
die "$0: parsing file '$file' failed (N='@cmdnames' D='$cmddesc')\n";
|
|
}
|
|
}
|
|
|
|
foreach (sort keys %entries)
|
|
{
|
|
my $prefix = "\t" x 5 . ' ';
|
|
my $id = $_;
|
|
$id =~ s/ /_/g;
|
|
my $synopsis = "\"$entries{$_}{cmdsynopsis}\"";
|
|
$synopsis =~ s/\\n/\\n"\n$prefix"/g;
|
|
my @args =
|
|
("buf", $synopsis, map("_(\"$_\")", @{ $entries{$_}{params} }));
|
|
print HFILE "extern void sql_help_$id(PQExpBuffer buf);\n";
|
|
print CFILE "void
|
|
sql_help_$id(PQExpBuffer buf)
|
|
{
|
|
\tappendPQExpBuffer(" . join(",\n$prefix", @args) . ");
|
|
}
|
|
|
|
";
|
|
}
|
|
|
|
print HFILE "
|
|
|
|
static const struct _helpStruct QL_HELP[] = {
|
|
";
|
|
foreach (sort keys %entries)
|
|
{
|
|
my $id = $_;
|
|
$id =~ s/ /_/g;
|
|
print HFILE " { \"$_\",
|
|
N_(\"$entries{$_}{cmddesc}\"),
|
|
sql_help_$id,
|
|
$entries{$_}{nl_count} },
|
|
|
|
";
|
|
}
|
|
|
|
print HFILE "
|
|
{ NULL, NULL, NULL } /* End of list marker */
|
|
};
|
|
|
|
|
|
#define QL_HELP_COUNT "
|
|
. scalar(keys %entries)
|
|
. " /* number of help items */
|
|
#define QL_MAX_CMD_LEN $maxlen /* largest strlen(cmd) */
|
|
|
|
|
|
#endif /* $define */
|
|
";
|
|
|
|
close CFILE;
|
|
close HFILE;
|
|
closedir DIR;
|