|
Packit |
6c4009 |
#!/usr/bin/perl
|
|
Packit |
6c4009 |
# Generate the Summary of Library Facilities (summary.texi).
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Copyright (C) 2017-2018 Free Software Foundation, Inc.
|
|
Packit |
6c4009 |
# This file is part of the GNU C Library.
|
|
Packit |
6c4009 |
# Contributed by Rical Jasan <ricaljasan@pacific.net>, 2017.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# The GNU C Library is free software; you can redistribute it and/or
|
|
Packit |
6c4009 |
# modify it under the terms of the GNU Lesser General Public License
|
|
Packit |
6c4009 |
# as published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
6c4009 |
# the License, or (at your option) any later version.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# The GNU C Library is distributed in the hope that it will be useful,
|
|
Packit |
6c4009 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
6c4009 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
6c4009 |
# Lesser General Public License for more details.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# You should have received a copy of the GNU Lesser General Public
|
|
Packit |
6c4009 |
# License along with the GNU C Library; if not, see
|
|
Packit |
6c4009 |
# <http://www.gnu.org/licenses/>.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Anything declared in a header or defined in a standard should have
|
|
Packit |
6c4009 |
# its origins annotated using the @standards macro (see macro.texi).
|
|
Packit |
6c4009 |
# This script checks all such elements in the manual (generally,
|
|
Packit |
6c4009 |
# @def|item*-commands), ensuring annotations are present and correct.
|
|
Packit |
6c4009 |
# If any errors are detected, they are all reported at the end and
|
|
Packit |
6c4009 |
# failure is indicated.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
use strict;
|
|
Packit |
6c4009 |
use warnings;
|
|
Packit |
6c4009 |
use locale;
|
|
Packit |
6c4009 |
use File::Basename;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
$| = 1;
|
|
Packit |
6c4009 |
my $script = basename $0;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
&help if $ARGV[0] eq "--help"; # Will exit(0).
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
my @texis = @ARGV;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Various regexes.
|
|
Packit |
6c4009 |
my $nde = qr/^\@node /;
|
|
Packit |
6c4009 |
my $def = qr/^\@def/;
|
|
Packit |
6c4009 |
my $itm = qr/^\@item /;
|
|
Packit |
6c4009 |
my $itms = qr/^\@itemx? /; # Don't match @itemize.
|
|
Packit |
6c4009 |
my $ann = qr/^\@(def\w+|item)x? /; # Annotatable.
|
|
Packit |
6c4009 |
my $std = qr/^\@standards\{/;
|
|
Packit |
6c4009 |
my $stx = qr/^\@standardsx\{/;
|
|
Packit |
6c4009 |
my $stds = qr/^\@standardsx?\{/;
|
|
Packit |
6c4009 |
my $strict_std = qr/^\@standards\{([^,]+, )[^,\}]+\}$/;
|
|
Packit |
6c4009 |
my $strict_stx = qr/^\@standardsx\{([^,]+, ){2}[^,\}]+\}$/;
|
|
Packit |
6c4009 |
my $lcon = qr/([vf]?table|itemize|enumerate)/;
|
|
Packit |
6c4009 |
my $list = qr/^\@${lcon}/;
|
|
Packit |
6c4009 |
my $endl = qr/^\@end ${lcon}/;
|
|
Packit |
6c4009 |
my $ign = qr/^\@ignore/;
|
|
Packit |
6c4009 |
my $eig = qr/^\@end ignore/;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Global scope.
|
|
Packit |
6c4009 |
my $node;
|
|
Packit |
6c4009 |
our $texi;
|
|
Packit |
6c4009 |
my $input;
|
|
Packit |
6c4009 |
my %entries;
|
|
Packit |
6c4009 |
my %errors;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
for $texi (@texis) {
|
|
Packit |
6c4009 |
open $input, '<', $texi or die "open $texi: $!";
|
|
Packit |
6c4009 |
while (my $line = <$input>) {
|
|
Packit |
6c4009 |
if ($line =~ $nde) {
|
|
Packit |
6c4009 |
$node = &get_node($line);
|
|
Packit |
6c4009 |
} elsif ($line =~ $def) {
|
|
Packit |
6c4009 |
&process_annotation($line);
|
|
Packit |
6c4009 |
} elsif ($line =~ $list) {
|
|
Packit |
6c4009 |
&process_list($1); # @items occur in list or table context.
|
|
Packit |
6c4009 |
} elsif ($line =~ $stds) {
|
|
Packit |
6c4009 |
&record_error("Misplaced annotation", ["[$.] ".$line]);
|
|
Packit |
6c4009 |
} elsif ($line =~ $ign) {
|
|
Packit |
6c4009 |
while (<$input> !~ $eig) {}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
close $input or die "close $texi: $!";
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Disabled until annotations are complete.
|
|
Packit |
6c4009 |
&print_errors() if %errors && 0; # Will exit(1).
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
print("\@c DO NOT EDIT THIS FILE!\n".
|
|
Packit |
6c4009 |
"\@c This file is generated by $script from the Texinfo sources.\n".
|
|
Packit |
6c4009 |
"\@c The \@items are \@include'd from a \@table in header.texi.\n\n");
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
&print_entry($_) for sort keys %entries;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Processes an annotatable element, including any subsequent elements
|
|
Packit |
6c4009 |
# in an @*x chain, ensuring @standards are present, with valid syntax,
|
|
Packit |
6c4009 |
# either recording any errors detected or creating Summary entries.
|
|
Packit |
6c4009 |
# This function is the heart of the script.
|
|
Packit |
6c4009 |
#
|
|
Packit |
6c4009 |
# Prototypes and standards are gathered into separate lists and used
|
|
Packit |
6c4009 |
# to evaluate the completeness and correctness of annotations before
|
|
Packit |
6c4009 |
# generating the Summary entries. "Prototype" is used to refer to an
|
|
Packit |
6c4009 |
# element's entire definition while avoiding conflation with
|
|
Packit |
6c4009 |
# @def*-commands. "Element" is strictly used here to refer to the
|
|
Packit |
6c4009 |
# name extracted from the prototype, as used in @standardsx, for
|
|
Packit |
6c4009 |
# sorting the Summary.
|
|
Packit |
6c4009 |
sub process_annotation
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
my $line = shift;
|
|
Packit |
6c4009 |
my (@prototypes, @standards, $i, @tmp);
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Gather prototypes and standards.
|
|
Packit |
6c4009 |
push @prototypes, $line;
|
|
Packit |
6c4009 |
while ($line = <$input>) {
|
|
Packit |
6c4009 |
last if $line !~ $ann;
|
|
Packit |
6c4009 |
push @prototypes, $line;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
if ($line !~ $stds) { # The fundamental error.
|
|
Packit |
6c4009 |
return &record_error('Missing annotation', \@prototypes);
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
push @standards, $line;
|
|
Packit |
6c4009 |
push @standards, $line while ($line = <$input>) =~ $stds;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# If next line is an @item, seek back to catch it on the next
|
|
Packit |
6c4009 |
# iteration. This avoids imposing a non-Texinfo syntax
|
|
Packit |
6c4009 |
# requirement of blank lines between consecutive annotated @items.
|
|
Packit |
6c4009 |
if ($line =~ $itm) {
|
|
Packit |
6c4009 |
seek $input, -length($line), 1 or die "seek: $!";
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Strict check for syntax errors. Other matches are loose, which
|
|
Packit |
6c4009 |
# aids error detection and reporting by ensuring things that look
|
|
Packit |
6c4009 |
# like standards aren't simply passed over, but caught here.
|
|
Packit |
6c4009 |
for ($i=0; $i<@standards; ++$i) {
|
|
Packit |
6c4009 |
my $standard = $standards[$i];
|
|
Packit |
6c4009 |
if ($standard !~ $strict_std && $standard !~ $strict_stx) {
|
|
Packit |
6c4009 |
push @tmp, $standard;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
return &record_error('Invalid syntax', \@tmp) if @tmp;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# @standardsx should not be in non-@*x chains.
|
|
Packit |
6c4009 |
if (@prototypes == 1) {
|
|
Packit |
6c4009 |
for ($i=0; $i<@standards; ++$i) {
|
|
Packit |
6c4009 |
return &record_error('Misplaced @standardsx', \@prototypes)
|
|
Packit |
6c4009 |
if $standards[$i] =~ $stx;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
# @standards may only occur once in @*x chains, at the beginning.
|
|
Packit |
6c4009 |
if (@prototypes > 1) {
|
|
Packit |
6c4009 |
for ($i=1; $i<@standards; ++$i) {
|
|
Packit |
6c4009 |
return &record_error('Misplaced @standards', \@prototypes)
|
|
Packit |
6c4009 |
if $standards[$i] =~ $std;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# The @standards are aligned.
|
|
Packit |
6c4009 |
&add_entries(\@prototypes, \@standards);
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Goes through the prototypes, cleaning them up and extracting the
|
|
Packit |
6c4009 |
# elements, pairing them with the appropriate annotations to create
|
|
Packit |
6c4009 |
# Summary entries.
|
|
Packit |
6c4009 |
sub add_entries
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
my ($prototypes, $standards) = @_;
|
|
Packit |
6c4009 |
my $isx = @{$prototypes} > 1 ? 1 : 0;
|
|
Packit |
6c4009 |
my $allx = $standards->[0] =~ $stx ? 1 : 0;
|
|
Packit |
6c4009 |
my ($defstd, $defhdr, %standardsx, $i, $j);
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Grab the default annotation and index any @standardsx. Take
|
|
Packit |
6c4009 |
# care in case there is no default.
|
|
Packit |
6c4009 |
if ($isx) {
|
|
Packit |
6c4009 |
if (!$allx) {
|
|
Packit |
6c4009 |
($defstd, $defhdr)
|
|
Packit |
6c4009 |
= $standards->[0] =~ /${std}([^,]+), (.*)\}$/;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
for ($i = $allx ? 0 : 1; $i<@{$standards}; ++$i) {
|
|
Packit |
6c4009 |
my ($e, $s, $h)
|
|
Packit |
6c4009 |
= $standards->[$i] =~ /${stx}([^,]+), ([^,]+), (.*)\}$/;
|
|
Packit |
6c4009 |
push @{$standardsx{$e}{hs}}, [$h, $s];
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
for ($i=0; $i<@{$prototypes}; ++$i) {
|
|
Packit |
6c4009 |
my $e = &get_element($prototypes->[$i]);
|
|
Packit |
6c4009 |
my $p = &get_prototype($prototypes->[$i]);
|
|
Packit |
6c4009 |
my ($s, $h);
|
|
Packit |
6c4009 |
if ($isx && exists $standardsx{$e}) {
|
|
Packit |
6c4009 |
for ($j=0; $j<@{$standardsx{$e}{hs}}; ++$j) {
|
|
Packit |
6c4009 |
$h = $standardsx{$e}{hs}[$j]->[0];
|
|
Packit |
6c4009 |
$s = $standardsx{$e}{hs}[$j]->[1];
|
|
Packit |
6c4009 |
&record_entry($e, $p, $h, $s, $node);
|
|
Packit |
6c4009 |
++$standardsx{$e}{seen};
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
} elsif ($isx && $allx) {
|
|
Packit |
6c4009 |
&record_error('Missing annotation', [$prototypes->[$i]]);
|
|
Packit |
6c4009 |
} elsif ($isx) {
|
|
Packit |
6c4009 |
&record_entry($e, $p, $defhdr, $defstd, $node);
|
|
Packit |
6c4009 |
} else {
|
|
Packit |
6c4009 |
for ($j=0; $j<@{$standards}; ++$j) {
|
|
Packit |
6c4009 |
($s, $h) = $standards->[$j] =~ /${std}([^,]+), ([^,\}]+)\}$/;
|
|
Packit |
6c4009 |
&record_entry($e, $p, $h, $s, $node);
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Check if there were any unmatched @standardsx.
|
|
Packit |
6c4009 |
for my $e (keys %standardsx) {
|
|
Packit |
6c4009 |
if (!exists $standardsx{$e}{seen}) {
|
|
Packit |
6c4009 |
&record_error('Spurious @standardsx', [$e."\n"])
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Stores a Summary entry in %entries. May be called multiple times
|
|
Packit |
6c4009 |
# per element if multiple header and standard annotations exist. Also
|
|
Packit |
6c4009 |
# keys on prototypes, as some elements have multiple prototypes. See
|
|
Packit |
6c4009 |
# isnan in arith.texi for one example.
|
|
Packit |
6c4009 |
sub record_entry
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
my ($ele, $proto, $hdr, $std, $node) = @_;
|
|
Packit |
6c4009 |
push @{$entries{$ele}{$proto}}, [$hdr, $std, $node];
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Processes list or table contexts, with nesting.
|
|
Packit |
6c4009 |
sub process_list
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
my $type = shift;
|
|
Packit |
6c4009 |
my $in_vtbl = $type eq "vtable" ? 1 : 0;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
while (my $line = <$input>) {
|
|
Packit |
6c4009 |
if ($line =~ $itms) {
|
|
Packit |
6c4009 |
next if ! $in_vtbl; # Not an annotatable context.
|
|
Packit |
6c4009 |
&process_annotation($line);
|
|
Packit |
6c4009 |
} elsif ($line =~ $def) {
|
|
Packit |
6c4009 |
&process_annotation($line);
|
|
Packit |
6c4009 |
} elsif ($line =~ $stds) {
|
|
Packit |
6c4009 |
&record_error('Misplaced annotation', ["[$.] ".$line]);
|
|
Packit |
6c4009 |
} elsif ($line =~ $endl) {
|
|
Packit |
6c4009 |
return; # All done.
|
|
Packit |
6c4009 |
} elsif ($line =~ $list) {
|
|
Packit |
6c4009 |
&process_list($1); # Nested list.
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Returns the current node from an @node line. Used for referencing
|
|
Packit |
6c4009 |
# from the Summary.
|
|
Packit |
6c4009 |
sub get_node
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
my $line = shift;
|
|
Packit |
6c4009 |
chomp $line;
|
|
Packit |
6c4009 |
$line =~ s/$nde//;
|
|
Packit |
6c4009 |
my ($n) = split ',', $line;
|
|
Packit |
6c4009 |
return $n
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Returns the cleaned up prototype from @def|item* lines.
|
|
Packit |
6c4009 |
sub get_prototype
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
my $dfn = shift;
|
|
Packit |
6c4009 |
chomp $dfn;
|
|
Packit |
6c4009 |
$dfn =~ s/\s+/ /g; # Collapse whitespace.
|
|
Packit |
6c4009 |
$dfn =~ s/ \{([^\}]*)\} / $1 /g; # Remove grouping braces.
|
|
Packit |
6c4009 |
$dfn =~ s/^\@\S+ //; # Remove @-command.
|
|
Packit |
6c4009 |
$dfn =~ s/^Macro //i; # Scrape off cruft...
|
|
Packit |
6c4009 |
$dfn =~ s/^Data Type //i;
|
|
Packit |
6c4009 |
$dfn =~ s/^Variable //i;
|
|
Packit |
6c4009 |
$dfn =~ s/^Deprecated Function //i;
|
|
Packit |
6c4009 |
$dfn =~ s/^SVID Macro //i;
|
|
Packit |
6c4009 |
$dfn =~ s/^Obsolete function //i;
|
|
Packit |
6c4009 |
$dfn =~ s/^Constant //i;
|
|
Packit |
6c4009 |
$dfn =~ s/^Type //i;
|
|
Packit |
6c4009 |
$dfn =~ s/^Function //i;
|
|
Packit |
6c4009 |
$dfn =~ s/^\{(.*)\}$/$1/; # Debrace yourself.
|
|
Packit |
6c4009 |
$dfn =~ s/^\{([^\}]*)\} /$1 /; # These ones too.
|
|
Packit |
6c4009 |
return $dfn;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Returns an annotated element's name.
|
|
Packit |
6c4009 |
#
|
|
Packit |
6c4009 |
# Takes a line defining an annotatable element (e.g., @def|item*),
|
|
Packit |
6c4009 |
# splitting it on whitespace. The element is generally detected as
|
|
Packit |
6c4009 |
# the member immediately preceding the first parenthesized expression
|
|
Packit |
6c4009 |
# (e.g., a function), or the last token in the list. Some additional
|
|
Packit |
6c4009 |
# cleanup is applied to the element before returning it.
|
|
Packit |
6c4009 |
sub get_element
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
my $i = 0;
|
|
Packit |
6c4009 |
my @toks = split /\s+/, shift;
|
|
Packit |
6c4009 |
# tzname array uses '['; don't match function pointers.
|
|
Packit |
6c4009 |
++$i while $toks[$i] && $toks[$i] !~ /^[\(\[](?!\*)/;
|
|
Packit |
6c4009 |
$toks[$i-1] =~ s/^\*//; # Strip pointer type syntax.
|
|
Packit |
6c4009 |
$toks[$i-1] =~ s/^\{?([^\}]+)\}?$/$1/; # Strip braces.
|
|
Packit |
6c4009 |
$toks[$i-1] =~ s/^\(\*([^\)]+)\)$/$1/; # Function pointers.
|
|
Packit |
6c4009 |
return $toks[$i-1];
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Records syntax errors detected in the manual related to @standards.
|
|
Packit |
6c4009 |
# The @def|item*s are grouped by file, then errors, to make it easier
|
|
Packit |
6c4009 |
# to track down exactly where and what the problems are.
|
|
Packit |
6c4009 |
sub record_error
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
my ($err, $list) = @_;
|
|
Packit |
6c4009 |
push @{$errors{$texi}{$err}}, $_ for (@{$list});
|
|
Packit |
6c4009 |
return 0;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Reports all detected errors and exits with failure. Indentation is
|
|
Packit |
6c4009 |
# used for readability, and "ERROR" is used for visibility.
|
|
Packit |
6c4009 |
sub print_errors
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
for $texi (sort keys %errors) {
|
|
Packit |
6c4009 |
print STDERR "ERRORS in $texi:\n";
|
|
Packit |
6c4009 |
for my $err (sort keys %{$errors{$texi}}) {
|
|
Packit |
6c4009 |
print STDERR " $err:\n";
|
|
Packit |
6c4009 |
print STDERR " $_" for (@{$errors{$texi}{$err}});
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
print(STDERR "\nFor a description of expected syntax, see ".
|
|
Packit |
6c4009 |
"\`$script --help'\n\n");
|
|
Packit |
6c4009 |
exit 1;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Prints an entry in the Summary.
|
|
Packit |
6c4009 |
#
|
|
Packit |
6c4009 |
# All the blank lines in summary.texi may seem strange at first, but
|
|
Packit |
6c4009 |
# they have significant impact on how Texinfo renders the output.
|
|
Packit |
6c4009 |
# Essentially, each line is its own paragraph. There is a @comment
|
|
Packit |
6c4009 |
# with the element name, arguably unnecessary, but useful for seeing
|
|
Packit |
6c4009 |
# the sorting order and extracted element names, and maintains the
|
|
Packit |
6c4009 |
# format established by summary.awk. Each @item in the @table is the
|
|
Packit |
6c4009 |
# prototype, which may be anything from just a variable name to a
|
|
Packit |
6c4009 |
# function declaration. The body of each @item contains lines
|
|
Packit |
6c4009 |
# annotating the headers and standards each element is declared
|
|
Packit |
6c4009 |
# in/comes from, with a reference to the @node documenting the element
|
|
Packit |
6c4009 |
# wrt. each header and standard combination.
|
|
Packit |
6c4009 |
sub print_entry
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
my $element = shift;
|
|
Packit |
6c4009 |
for my $prototype (sort keys %{$entries{$element}}) {
|
|
Packit |
6c4009 |
print "\@comment $element\n\@item $prototype\n\n";
|
|
Packit |
6c4009 |
for (@{$entries{$element}{$prototype}}) {
|
|
Packit |
6c4009 |
my ($header, $standard, $node)
|
|
Packit |
6c4009 |
= ($_->[0], $_->[1], $_->[2]);
|
|
Packit |
6c4009 |
if ($header =~ /^\(none\)$/i) {
|
|
Packit |
6c4009 |
$header = "\@emph{no header}";
|
|
Packit |
6c4009 |
} elsif ($header =~ /\(optional\)$/) {
|
|
Packit |
6c4009 |
$header =~ s/^(\S+) \((.*)\)$/\@file{$1} \@emph{$2}/;
|
|
Packit |
6c4009 |
} elsif ($header ne '???') {
|
|
Packit |
6c4009 |
$header = "\@file{$header}";
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
print "$header ($standard): \@ref{$node}.\n\n";
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# Document the syntax of @standards.
|
|
Packit |
6c4009 |
sub help
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
print "$script ";
|
|
Packit |
6c4009 |
print <<'EOH';
|
|
Packit |
6c4009 |
generates the Summary of Library Facilities (summary.texi)
|
|
Packit |
6c4009 |
from @standards and @standardsx macros in the Texinfo sources (see
|
|
Packit |
6c4009 |
macros.texi). While generating the Summary, it also checks that
|
|
Packit |
6c4009 |
@standards are used, correctly.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
In general, any @def*-command or @item in a @vtable is considered
|
|
Packit |
6c4009 |
annotatable. "Misplaced annotation" refers to @standards macros
|
|
Packit |
6c4009 |
detected outside an annotatable context. "Missing annotation" refers
|
|
Packit |
6c4009 |
to annotatable elements without @standards. @standards are expected
|
|
Packit |
6c4009 |
to immediately follow the elements being annotated. In @*x lists,
|
|
Packit |
6c4009 |
@standards sets the default annotation and may only occur as the first
|
|
Packit |
6c4009 |
annotation ("Misplaced @standards"). @standardsx may not be used
|
|
Packit |
6c4009 |
outside @*x lists ("Misplaced @standardsx"). "Spurious @standardsx"
|
|
Packit |
6c4009 |
refers to otherwise valid @standardsx macros that were not matched to
|
|
Packit |
6c4009 |
an element in an @*x list. "Invalid syntax" means just that.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
The syntax of @standards annotations is designed to accomodate
|
|
Packit |
6c4009 |
multiple header and standards annotations, as necessary.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
Examples:
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
@deftp FOO
|
|
Packit |
6c4009 |
@standards{STD, HDR}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
@defvar BAR
|
|
Packit |
6c4009 |
@standards{STD, HDR1}
|
|
Packit |
6c4009 |
@standards{STD, HDR2}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
@deftypefun foo
|
|
Packit |
6c4009 |
@deftypefunx fool
|
|
Packit |
6c4009 |
@standards{STD, HDR}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
@item bar
|
|
Packit |
6c4009 |
@itemx baz
|
|
Packit |
6c4009 |
@standardsx{bar, STD1, HDR1}
|
|
Packit |
6c4009 |
@standardsx{baz, STD1, HDR1}
|
|
Packit |
6c4009 |
@standardsx{baz, STD2, HDR2}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
Note that @standardsx deviates from the usual Texinfo syntax in that
|
|
Packit |
6c4009 |
it is optional and may be used without @standards.
|
|
Packit |
6c4009 |
EOH
|
|
Packit |
6c4009 |
; exit 0;
|
|
Packit |
6c4009 |
}
|