diff --git a/manual/Makefile b/manual/Makefile
index f2f694f..d6d8c27 100644
--- a/manual/Makefile
+++ b/manual/Makefile
@@ -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
diff --git a/manual/check-stds.pl b/manual/check-stds.pl
new file mode 100755
index 0000000..b4b7146
--- /dev/null
+++ b/manual/check-stds.pl
@@ -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";
+	}
+    }
+}
diff --git a/manual/summary.awk b/manual/summary.awk
index 7f721e9..e6e0c49 100644
--- a/manual/summary.awk
+++ b/manual/summary.awk
@@ -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
