aboutsummaryrefslogtreecommitdiff
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 0000000..b3e447f
--- /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 "}";
+}