about summary refs log tree commit diff
path: root/manual/summary-check.awk
diff options
context:
space:
mode:
Diffstat (limited to 'manual/summary-check.awk')
-rw-r--r--manual/summary-check.awk139
1 files changed, 139 insertions, 0 deletions
diff --git a/manual/summary-check.awk b/manual/summary-check.awk
new file mode 100644
index 0000000000..b3e447fa1d
--- /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 "}";
+}