This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH roland/manual-check] Add test case for declarations in manual.


I did most of the work for a test that validates the declarations in the
manual against the actual code.  It was by using this that I found all the
errors I just fixed.  There are more real errors still to be fixed.

I'm not putting this in just yet because it still has some issues leading
to false errors:

1. It's one big source file for everything, so it can't handle mutually
   incompatible headers: sys/vlimit.h vs math.h (bits/inf.h) for INFINITY.
2. __SOCKADDR_ARG
3. Official prototypes not matching actual prototypes because of enums:
   __itimer_which_t, __priority_which_t
4. Confused by special macros: offsetof, va_*
5. Cases where the manual is wrong but needs more fixed than just the
   prototype: setpgrp, wcstok, mremap, ioctl(?)


Thanks,
Roland


2013-02-11  Roland McGrath  <roland@hack.frob.com>

	* manual/summary.awk: Print "@c FILE LINENO FLAVOR" lines between the
	sort key comment and the @item.  Grok "(optional)" final token on
	header @comment lines and put it on the leading @comment in output.
	* manual/conf.texi (General Limits): Add (optional) for ARG_MAX,
	CHILD_MAX, OPEN_MAX, STREAM_MAX, TZNAME_MAX.
	(Utility Limits): Likewise for EQUIV_CLASS_MAX.
	(Limits for Files): Likewise for LINK_MAX.
	* manual/terminal.texi (Local Modes): Likewise for ALTWERASE and
	NOKERNINFO.
	(Control Modes): Likewise for CCTS_OFLOW, CRTS_IFLOW, MDMBUF, CIGNORE.
	(Output Modes): Likewise for ONOEOT, OXTABS.
	(Signal Characters): Likewise for VDSUSP.
	(Other Special): Likewise for VSTATUS.
	* manual/errno.texi (Error Codes): Likewise for EAUTH, ENEEDAUTH,
	EBACKGROUND, EDIED, ED, EGREGIOUS, EIEIO, EGRATUITOUS, EBADRPC,
	ERPCMISMATCH, EPROGUNAVAIL, EPROGMISMATCH, EPROCUNAVAIL, EFTYPE,
	EPROCLIM.
	* manual/time.texi (Processor Time): Likewise for CLK_TCK.
	* manual/llio.texi (Access Modes): Likewise for O_READ, O_WRITE, O_EXEC.
	(Open-time Flags): Likewise for O_SHLOCK, O_EXLOCK, O_IGNORE_CTTY,
	O_NOLINK, O_NOTRANS.
	* manual/signal.texi (Program Error Signals): Likewise for SIGEMT.
	(Miscellaneous Signals): Likewise for SIGINFO.
	(Operation Error Signals): Likewise for SIGLOST.
	* manual/summary-check.awk: New file.
	* manual/Makefile ($(objpfx)summary-check.c): New target.
	(tests): New variable.

	* include/sys/auxv.h: New file.

--- /dev/null
+++ b/include/sys/auxv.h
@@ -0,0 +1 @@
+#include <misc/sys/auxv.h>
--- a/manual/Makefile
+++ b/manual/Makefile
@@ -47,6 +47,7 @@ add-chapters = $(wildcard $(foreach d, $(add-ons), ../$d/$d.texi))
 appendices = lang.texi header.texi install.texi maint.texi platform.texi \
 	     contrib.texi
 licenses = freemanuals.texi lgpl-2.1.texi fdl-1.3.texi
+tests = summary-check
 
 -include $(objpfx)texis
 $(objpfx)texis: texis.awk $(chapters) $(add-chapters) $(appendices) $(licenses)
@@ -93,6 +94,10 @@ $(objpfx)stamp-summary: summary.awk $(filter-out $(objpfx)summary.texi, \
 	$(move-if-change) $(objpfx)summary-tmp $(objpfx)summary.texi
 	touch $@
 
+$(objpfx)summary-check.c: summary-check.awk $(objpfx)summary.texi
+	$(AWK) -f $^ > $@.new
+	mv -f $@.new $@
+
 # Generate a file which can be added to the `dir' content to provide direct
 # access to the documentation of the function, variables, and other
 # definitions.
--- a/manual/conf.texi
+++ b/manual/conf.texi
@@ -56,7 +56,7 @@ with @samp{_POSIX}, which gives the lowest value that the limit is
 allowed to have on @emph{any} POSIX system.  @xref{Minimums}.
 
 @cindex limits, program argument size
-@comment limits.h
+@comment limits.h (optional)
 @comment POSIX.1
 @deftypevr Macro int ARG_MAX
 If defined, the unvarying maximum combined length of the @var{argv} and
@@ -64,7 +64,7 @@ If defined, the unvarying maximum combined length of the @var{argv} and
 @end deftypevr
 
 @cindex limits, number of processes
-@comment limits.h
+@comment limits.h (optional)
 @comment POSIX.1
 @deftypevr Macro int CHILD_MAX
 If defined, the unvarying maximum number of processes that can exist
@@ -74,7 +74,7 @@ Resources}.
 @end deftypevr
 
 @cindex limits, number of open files
-@comment limits.h
+@comment limits.h (optional)
 @comment POSIX.1
 @deftypevr Macro int OPEN_MAX
 If defined, the unvarying maximum number of files that a single process
@@ -82,7 +82,7 @@ can have open simultaneously.  In BSD and GNU, this is controlled
 by the @code{RLIMIT_NOFILE} resource limit; @pxref{Limits on Resources}.
 @end deftypevr
 
-@comment limits.h
+@comment limits.h (optional)
 @comment POSIX.1
 @deftypevr Macro int STREAM_MAX
 If defined, the unvarying maximum number of streams that a single
@@ -90,7 +90,7 @@ process can have open simultaneously.  @xref{Opening Streams}.
 @end deftypevr
 
 @cindex limits, time zone name length
-@comment limits.h
+@comment limits.h (optional)
 @comment POSIX.1
 @deftypevr Macro int TZNAME_MAX
 If defined, the unvarying maximum length of a time zone name.
@@ -1539,7 +1539,7 @@ there is no actual limit except that imposed by the available virtual
 memory, but there is no way that the library can tell you this.)
 @end deftypevr
 
-@comment limits.h
+@comment limits.h (optional)
 @comment POSIX.2
 @deftypevr Macro int EQUIV_CLASS_MAX
 The maximum number of weights that can be assigned to an entry of the
--- a/manual/errno.texi
+++ b/manual/errno.texi
@@ -714,7 +714,7 @@ Directory not empty, where an empty directory was expected.  Typically,
 this error occurs when you are trying to delete a directory.
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment BSD: Too many processes
 @deftypevr Macro int EPROCLIM
 @comment errno 67 @c DO NOT REMOVE
@@ -758,35 +758,35 @@ already specifies an NFS-mounted file.
 properly on @gnuhurdsystems{}, making this error code impossible.)
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment BSD: RPC struct is bad
 @deftypevr Macro int EBADRPC
 @comment errno 72 @c DO NOT REMOVE
 ???
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment BSD: RPC version wrong
 @deftypevr Macro int ERPCMISMATCH
 @comment errno 73 @c DO NOT REMOVE
 ???
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment BSD: RPC program not available
 @deftypevr Macro int EPROGUNAVAIL
 @comment errno 74 @c DO NOT REMOVE
 ???
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment BSD: RPC program version wrong
 @deftypevr Macro int EPROGMISMATCH
 @comment errno 75 @c DO NOT REMOVE
 ???
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment BSD: RPC bad procedure for program
 @deftypevr Macro int EPROCUNAVAIL
 @comment errno 76 @c DO NOT REMOVE
@@ -803,7 +803,7 @@ it can result from an operation to an NFS server running another
 operating system.
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment BSD: Inappropriate file type or format
 @deftypevr Macro int EFTYPE
 @comment errno 79 @c DO NOT REMOVE
@@ -814,14 +814,14 @@ On some systems @code{chmod} returns this error if you try to set the
 sticky bit on a non-directory file; @pxref{Setting Permissions}.
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment BSD: Authentication error
 @deftypevr Macro int EAUTH
 @comment errno 80 @c DO NOT REMOVE
 ???
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment BSD: Need authenticator
 @deftypevr Macro int ENEEDAUTH
 @comment errno 81 @c DO NOT REMOVE
@@ -865,7 +865,7 @@ While decoding a multibyte character the function came along an invalid
 or an incomplete sequence of bytes or the given wide character is invalid.
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment GNU: Inappropriate operation for background process
 @deftypevr Macro int EBACKGROUND
 @comment errno 100 @c DO NOT REMOVE
@@ -877,7 +877,7 @@ it into a @code{SIGTTIN} or @code{SIGTTOU} signal.  @xref{Job Control},
 for information on process groups and these signals.
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment GNU: Translator died
 @deftypevr Macro int EDIED
 @comment errno 101 @c DO NOT REMOVE
@@ -886,7 +886,7 @@ translated by a program and the translator program dies while starting
 up, before it has connected to the file.
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment GNU: ?
 @deftypevr Macro int ED
 @comment errno 102 @c DO NOT REMOVE
@@ -895,21 +895,21 @@ The experienced user will know what is wrong.
 @c Don't change it.
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment GNU: You really blew it this time
 @deftypevr Macro int EGREGIOUS
 @comment errno 103 @c DO NOT REMOVE
 You did @strong{what}?
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment GNU: Computer bought the farm
 @deftypevr Macro int EIEIO
 @comment errno 104 @c DO NOT REMOVE
 Go home and have a glass of warm, dairy-fresh milk.
 @end deftypevr
 
-@comment errno.h
+@comment errno.h (optional)
 @comment GNU: Gratuitous error
 @deftypevr Macro int EGRATUITOUS
 @comment errno 105 @c DO NOT REMOVE
--- a/manual/signal.texi
+++ b/manual/signal.texi
@@ -446,9 +446,9 @@ probably only see @code{SIGTRAP} if it is somehow executing bad
 instructions.
 @end deftypevr
 
-@comment signal.h
+@comment signal.h (optional)
 @comment BSD
-@deftypevr Macro int  SIGEMT
+@deftypevr Macro int SIGEMT
 Emulator trap; this results from certain unimplemented instructions
 which might be emulated in software, or the operating system's
 failure to properly emulate them.
@@ -456,7 +456,7 @@ failure to properly emulate them.
 
 @comment signal.h
 @comment Unix
-@deftypevr Macro int  SIGSYS
+@deftypevr Macro int SIGSYS
 Bad system call; that is to say, the instruction to trap to the
 operating system was executed, but the code number for the system call
 to perform was invalid.
@@ -798,7 +798,7 @@ Another cause of @code{SIGPIPE} is when you try to output to a socket
 that isn't connected.  @xref{Sending Data}.
 @end deftypevr
 
-@comment signal.h
+@comment signal.h (optional)
 @comment GNU
 @deftypevr Macro int SIGLOST
 @cindex lost resource signal
@@ -861,7 +861,7 @@ When the signal arrives, it should fetch the new screen size and
 reformat its display accordingly.
 @end deftypevr
 
-@comment signal.h
+@comment signal.h (optional)
 @comment BSD
 @deftypevr Macro int SIGINFO
 Information request.  On 4.4 BSD and @gnuhurdsystems{}, this signal is sent
--- a/manual/stdio.texi
+++ b/manual/stdio.texi
@@ -5053,26 +5053,26 @@ otherwise.
 
 @comment stdio.h
 @comment GNU
-@deftp {Data Type} cookie_read_function
+@deftp {Data Type} cookie_read_function_t
 This is the data type that the read function for a custom stream should have.
 If you declare the function as shown above, this is the type it will have.
 @end deftp
 
 @comment stdio.h
 @comment GNU
-@deftp {Data Type} cookie_write_function
+@deftp {Data Type} cookie_write_function_t
 The data type of the write function for a custom stream.
 @end deftp
 
 @comment stdio.h
 @comment GNU
-@deftp {Data Type} cookie_seek_function
+@deftp {Data Type} cookie_seek_function_t
 The data type of the seek function for a custom stream.
 @end deftp
 
 @comment stdio.h
 @comment GNU
-@deftp {Data Type} cookie_close_function
+@deftp {Data Type} cookie_close_function_t
 The data type of the close function for a custom stream.
 @end deftp
 
--- /dev/null
+++ b/manual/summary-check.awk
@@ -0,0 +1,139 @@
+# awk script to create a C file from summary.texinfo
+# Copyright (C) 2013 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# 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/>.
+
+# This script groks the summary.texi (summary.awk output) format.
+# It produces a compilable C file attempts to refer to each declaration
+# in summary.texi so as to verify that the types in the manual match the
+# types in the code.
+
+BEGIN {
+  wraps["@w{"] = 1;
+  wraps["@t{"] = 1;
+  wraps["@emph{"] = 1;
+
+  print "/* This file is generated by summary-check.awk; DO NOT EDIT!  */";
+  print "";
+}
+
+NF == 2 && $1 == "@comment" {
+  ident = $2;
+  optional = 0;
+  next
+}
+NF == 3 && $1 == "@comment" && $3 = "(optional)" {
+  ident = $2;
+  optional = 1;
+  next
+}
+NF >= 4 && $1 == "@c" {
+  source = $2;
+  lineno = $3;
+  flavor = $4;
+  for (i = 5; i <= NF; ++i)
+    flavor = flavor " " $i;
+  next
+}
+$1 == "@item" {
+  $1 = "";
+  gsub(/@var{[^}]+}/, "");
+  gsub(/@dots{}/, "...");
+  gsub(/@\*/, " ");
+  decl = $0 ";";
+  for (wrap in wraps) {
+    len = length(wrap);
+    while ((first = match(decl, wrap)) > 0) {
+      depth = 1;
+      for (i = first + len; i < length(decl); ++i) {
+        c = substr(decl, i, 1);
+        if (c == "{") ++depth;
+        else if (c == "}" && --depth == 0) {
+          left = substr(decl, 1, first - 1);
+          middle = substr(decl, first + len, i - (first + len));
+          right = substr(decl, i + 1);
+          decl = left middle right;
+          break;
+        }
+      }
+    }
+  }
+  sub(/\.\.\.,.+);/, "...);", decl); # execle
+  sub(/\[,[^],]+\]/, ", ...", decl); # open
+  next
+}
+
+/^@file{/ {
+  gsub(/[^a-zA-Z0-9_]/, "", ident);
+  undef = 1;
+  if (flavor ~ /@defvrx?/) {
+    # These are used for feature-test macros.  There is nothing we can test.
+    next;
+  }
+  if (flavor ~ /@itemx?/ || flavor == "@vindex") {
+    # These are used for macros, but we have no type information.
+    next;
+  }
+  if (flavor == "@defvar") {
+    # These are used for variables, but we have no type information.
+    next;
+  }
+  if (flavor == "@defmac") {
+    # These are used for function-like macros, but we have no type information.
+    next;
+  }
+  if (flavor ~ /^@deftypevrx? {Data type}$/ || flavor == "@deftp") {
+    # This is a type.  We can just test that it's usable.
+    decl = "extern " ident " test_" ident ";";
+  }
+  else if (flavor ~ /^@deftypevrx?/) {
+    # These are used for macros.
+    sub(ident, "test_" ident " (void) { return " ident "; }", decl);
+    undef = 0
+  }
+
+  if (decl ~ /float-type/ || decl ~ /real-floating/) {
+    # Special case: these are function-like macros that
+    # cannot be redeclared.  There isn't a simple way to test.
+    next
+  }
+
+  if (ident in seen)
+    next;
+  seen[ident] = 1
+
+  gsub(/,/, "");
+  for (i = 1; i <= NF && $i ~ /@file{[^}]+}/; ++i) {
+    header = gensub(/@file{([^}]+)}/, "\\1", 1, $i);
+    print "#include", "<" header ">";
+  }
+  if (optional)
+    print "#ifdef", ident;
+  else if (undef)
+    print "#undef", ident;
+  print "#", lineno, "\"" source "\"";
+  print decl;
+  if (optional)
+    print "#endif", "/*", ident, "*/";
+}
+
+END {
+  print "";
+  print "int main (void)";
+  print "{";
+  print "  return 0;";
+  print "}";
+}
--- a/manual/summary.awk
+++ b/manual/summary.awk
@@ -88,17 +88,22 @@ $1 == "@node" { node=$2;
 	      }
 
 $1 == "@comment" && $2 ~ /\.h$/ { header="@file{" $2 "}";
+                                  optional = 0;
+                                  if ($NF == "(optional)") {
+                                    optional = 1;
+                                    --NF;
+                                  }
 				  for (i = 3; i <= NF; ++i)
 				    header=header ", @file{" $i "}"
 				}
 
-$1 == "@comment" && $2 == "(none)" { header = -1; }
+$1 == "@comment" && $2 == "(none)" { header = -1; optional = 0; }
 
 $1 == "@comment" && header != 0 { std=$2;
 				  for (i=3;i<=NF;++i) std=std " " $i }
 
 header != 0 && $1 ~ /@def|@item|@vindex/ \
-	{ defn=""; name=""; curly=0; n=1;
+	{ defn=""; name=""; curly=0; n=1; flavor="";
 	  for (i = 2; i <= NF; ++i) {
 	    if ($i ~ /^{/ && $i !~ /}/) {
 	      curly=1
@@ -124,9 +129,15 @@ header != 0 && $1 ~ /@def|@item|@vindex/ \
 		  name=word
 		++n
 	      }
+              if (flavor == "") {
+                flavor = $1;
+                if (flavor ~ /^@deftypevrx?/)
+                  flavor = flavor " {" word "}";
+              }
 	    }
 	  }
-	  printf "@comment %s%c", name, 12 # FF
+	  printf "@comment %s%s%c", name, optional ? " (optional)" : "", 12 # FF
+	  printf "@c %s %d %s%c", FILENAME, FNR, flavor, 12
 	  printf "@item%s%c%c", defn, 12, 12
 	  if (header != -1) printf "%s ", header;
 	  printf "(%s):  @ref{%s}.%c\n", std, node, 12;
--- a/manual/terminal.texi
+++ b/manual/terminal.texi
@@ -752,27 +752,27 @@ This specifies eight bits per byte.
 The following four bits are BSD extensions; these exist only on BSD
 systems and @gnuhurdsystems{}.
 
-@comment termios.h
+@comment termios.h (optional)
 @comment BSD
 @deftypevr Macro tcflag_t CCTS_OFLOW
 If this bit is set, enable flow control of output based on the CTS wire
 (RS232 protocol).
 @end deftypevr
 
-@comment termios.h
+@comment termios.h (optional)
 @comment BSD
 @deftypevr Macro tcflag_t CRTS_IFLOW
 If this bit is set, enable flow control of input based on the RTS wire
 (RS232 protocol).
 @end deftypevr
 
-@comment termios.h
+@comment termios.h (optional)
 @comment BSD
 @deftypevr Macro tcflag_t MDMBUF
 If this bit is set, enable carrier-based flow control of output.
 @end deftypevr
 
-@comment termios.h
+@comment termios.h (optional)
 @comment BSD
 @deftypevr Macro tcflag_t CIGNORE
 If this bit is set, it says to ignore the control modes and line speed
@@ -940,7 +940,7 @@ attempt to write to the terminal.  @xref{Access to the Terminal}.
 The following bits are BSD extensions; they exist only on BSD systems
 and @gnuhurdsystems{}.
 
-@comment termios.h
+@comment termios.h (optional)
 @comment BSD
 @deftypevr Macro tcflag_t ALTWERASE
 This bit determines how far the WERASE character should erase.  The
@@ -1394,7 +1394,7 @@ mechanism, the program should send a @code{SIGTSTP} signal to the
 process group of the process, not just to the process itself.
 @xref{Signaling Another Process}.
 
-@comment termios.h
+@comment termios.h (optional)
 @comment BSD
 @deftypevr Macro int VDSUSP
 @cindex DSUSP character
@@ -1501,7 +1501,7 @@ output buffer.  Typing any other character resets the flag.
 This character is available on BSD systems and @gnulinuxhurdsystems{}.
 @end deftypevr
 
-@comment termios.h
+@comment termios.h (optional)
 @comment BSD
 @deftypevr Macro int VSTATUS
 @cindex STATUS character
--- a/manual/time.texi
+++ b/manual/time.texi
@@ -300,7 +300,7 @@ these are the actual amounts of time; not relative to any event.
 @xref{Creating a Process}.
 @end deftp
 
-@comment time.h
+@comment time.h (optional)
 @comment POSIX.1
 @deftypevr Macro int CLK_TCK
 This is an obsolete name for the number of clock ticks per second.  Use


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]