@@ -85,6 +85,7 @@ $(objpfx)summary.texi: $(objpfx)stamp-summary ;
$(objpfx)stamp-summary: summary.awk $(filter-out $(objpfx)summary.texi, \
$(texis-path))
$(SHELL) ./check-safety.sh $(filter-out $(objpfx)%, $(texis-path))
+ $(PERL) check-stds.pl $^
$(AWK) -f $^ | sort -t'' -df -k 1,1 | tr '\014' '\012' \
> $(objpfx)summary-tmp
$(move-if-change) $(objpfx)summary-tmp $(objpfx)summary.texi
new file mode 100755
@@ -0,0 +1,211 @@
+#!/usr/bin/perl
+# Copyright (C) 2016 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Rical Jasan <ricaljasan@pacific.net>, 2016.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# Complement summary.awk by finding entries within the manual that
+# require header and standards @comments, ensuring they have them,
+# and verifying their syntax. Also see summary.awk.
+
+use strict;
+use warnings;
+
+# Keep track of context.
+my @lines;
+my ($cur, $std, $hdr, $ctx) = (0, 1, 2, 3);
+
+# Error messages.
+my $missing_header = "Missing header.";
+my $missing_standard = "Missing standard.";
+
+# Accept files to check as args.
+my @texis = @ARGV;
+
+for (my $i=0; $i<@texis; $i++) {
+ # Probes is a special chapter...
+ if ($texis[$i] =~ /probes\.texi$/) {
+ splice(@texis, $i, 1);
+ last;
+ }
+}
+
+# @c-style comments aren't used.
+my $comment = qr/^\@comment /;
+# Strict check for header @comments, based on current practice.
+my $header = qr/${comment}(([\w\/]+\.h ?)+(\(optional\))?|\(none\))$/i;
+# Standards are free-form but do not contain @-commands.
+my $standard = qr/${comment}[^\@]+/;
+# All @def*-commands need annotation.
+my $def = qr/^\@def/;
+# Not all @items do; we'll know by context.
+my $item = qr/^\@itemx? /;
+# @items in @vtables must be annotated.
+my $vtable = qr/^\@vtable /;
+my $vtable_end = qr/^\@end vtable$/;
+# @tables must be recognized for recursion.
+my $table = qr/^\@table /;
+my $table_end = qr/\@end table$/;
+# Contexts we know need checking.
+my $table_or_list = qr/^\@v?table /;
+
+# For subsequent analysis.
+my %errors;
+
+# Global scope.
+my $input;
+
+for (@texis) {
+ open $input, '<', $_;
+ while ($lines[$cur] = <$input>)
+ {
+ if ($lines[$cur] =~ $def)
+ {
+ &check_annotations();
+ }
+ elsif ($lines[$cur] =~ $table_or_list)
+ {
+ &check_items();
+ }
+
+ &shuffle();
+ }
+ close $input;
+}
+
+if (%errors)
+{
+ &print_errors();
+ exit 1;
+}
+
+exit 0;
+
+sub shuffle
+{
+ $lines[$ctx] = $lines[$hdr] if $lines[$hdr];
+ $lines[$hdr] = $lines[$std] if $lines[$std];
+ $lines[$std] = $lines[$cur];
+}
+
+sub store_error
+{
+ push @{$errors{$_}}, {
+ errors => shift,
+ line => $lines[$cur],
+ standard => $lines[$std] ? $lines[$std] : undef,
+ header => $lines[$hdr] ? $lines[$hdr] : undef,
+ context => $lines[$ctx] ? $lines[$ctx] : undef,
+ };
+}
+
+sub check_annotations
+{
+ my @errors;
+
+ if (!$lines[$std] || $lines[$std] !~ $standard) {
+ push @errors, $missing_standard
+ }
+
+ if (!$lines[$hdr]) {
+ push @errors, $missing_header;
+ }
+ elsif ($lines[$hdr] !~ $header) {
+ if ($lines[$std] =~ $header) {
+ push @errors, $missing_standard;
+ } else {
+ push @errors, $missing_header;
+ }
+ }
+
+ &store_error(\@errors) if @errors;
+}
+
+sub check_items
+{
+ if ($lines[$cur] =~ $vtable)
+ {
+ &check_vtable();
+ }
+ elsif ($lines[$cur] =~ $table)
+ {
+ &check_table();
+ }
+}
+
+sub check_vtable
+{
+ &shuffle();
+ until (($lines[$cur] = <$input>) =~ $vtable_end)
+ {
+ # detect nested tables or lists.
+ if ($lines[$cur] =~ $table_or_list)
+ {
+ &check_items();
+ }
+ # vtable item
+ elsif ($lines[$cur] =~ $item)
+ {
+ &check_annotations();
+ }
+ elsif ($lines[$cur] =~ $def)
+ {
+ &check_annotations();
+ }
+ &shuffle();
+ }
+}
+
+sub check_table
+{
+ &shuffle();
+ until (($lines[$cur] = <$input>) =~ $table_end) {
+ # detect nested tables/lists.
+ if ($lines[$cur] =~ $table_or_list)
+ {
+ &check_items();
+ }
+ &shuffle();
+ }
+}
+
+sub print_errors
+{
+ for my $texi (sort keys %errors)
+ {
+ my $printed_texi = 0;
+
+ for (@{$errors{$texi}})
+ {
+ if (!$printed_texi)
+ {
+ print STDERR "****\nErrors detected in $texi:\n\n";
+ $printed_texi = 1;
+ }
+ print STDERR "----------------\n";
+ for my $error (@{$_->{errors}})
+ {
+ print STDERR "$error\n";
+ }
+ print STDERR "\n";
+ print STDERR "C:$_->{context}" if $_->{context};
+ print STDERR "H:$_->{header}" if $_->{header};
+ print STDERR "S:$_->{standard}" if $_->{standard};
+ print STDERR "L:$_->{line}";
+ print STDERR " ^^^^\n\n";
+ }
+ }
+}
@@ -17,9 +17,10 @@
# <http://www.gnu.org/licenses/>.
# This script recognizes sequences that look like:
-# @comment HEADER.h
+# @comment HEADER.h[ HEADER.h[...]]
# @comment STANDARD
# @def... ITEM | @item ITEM | @vindex ITEM
+# where STANDARD is essentially free-form.
BEGIN { header = 0;
nameword["@defun"]=1